感觉讲不清。。

2018/9/28 UPD:
可以单个翻也可以整段翻 然后就先靠单个翻把一段翻成一样的
大概就是从左往右翻一波再从右往左翻一波再整个翻翻看?
我在讲什么

#include <bits/stdc++.h> using namespace std; const int N=2501; string s; int n; int f[N][2],d[N][2],a[N][2]; template<class T> void checkmin(T &a,const T &b) { if (b<a) a=b; } template<class T> void checkmax(T &a,const T &b) { if (b>a) a=b; } class FlippingBitsDiv2 { public: int getmin( vector <string> S, int M ) ; }; int FlippingBitsDiv2::getmin(vector <string> ss, int m) { s=""; for(int i=0;i<ss.size();i++) s+=ss[i]; n=s.size(); memset(a,0,sizeof a); memset(f,0x3f,sizeof f); memset(d,0x3f,sizeof d); for(int i=0;i<n;i+=m) for(int j=0;j<m;j++) if (s[i+j]=='0') a[i/m+1][1]++; else a[i/m+1][0]++; n=n/m; f[0][0]=f[0][1]=0; for(int i=1;i<=n;i++){ f[i][0]=min(f[i-1][0]+a[i][0],f[i-1][1]+a[i][1]+1); f[i][1]=min(f[i-1][1]+a[i][1],f[i-1][0]+a[i][0]+1); f[i][0]=min(f[i][0],f[i][1]+1); f[i][1]=min(f[i][1],f[i][0]+1); } d[n+1][0]=d[n+1][1]=0; for(int i=n;i;i--){ d[i][0]=min(d[i+1][0]+a[i][0],d[i+1][1]+a[i][1]+1); d[i][1]=min(d[i+1][1]+a[i][1],d[i+1][0]+a[i][0]+1); d[i][0]=min(d[i][0],d[i][1]+1); d[i][1]=min(d[i][1],d[i][0]+1); } int ans=2e9; for(int i=1;i<=n;i++){ int s1=0,s0=0; for(int j=i;j<=n;j++){ s1+=a[j][1];s0+=a[j][0]; ans=min(ans,f[i-1][1]+d[j+1][1]+s1); ans=min(ans,f[i-1][0]+d[j+1][0]+s0+1); } } return ans; }