BZOJ1704. [Usaco2007 Mar]Face The Right Way 自动转身机
把状态看成 $01$,把序列状态差分,那么每次一个区间翻转即为差分序列两边翻转,最终状态就是差分值全为 $0$
对于每个差分值不为 $0$ 的位置,我们一定要把它翻转,而差分值为 $0$ 的位置一定不能翻转,从左到右扫一遍贪心翻转就行
枚举所有 $K$ 即可
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=1e4+7; int n,a[N],b[N],c[N],ans,cnt; bool check(int K) { for(int i=1;i<=n+1;i++) c[i]=b[i]; cnt=0; for(int i=1;i<=n+1;i++) { if(!c[i]) continue; if(i+K>n+1) return 0; c[i]=0; c[i+K]^=1; cnt++; } return 1; } int main() { n=read(); char ch[7]; for(int i=1;i<=n;i++) scanf("%s",ch),a[i]=(ch[0]=='B'); for(int i=1;i<=n+1;i++) b[i]=a[i-1]^a[i]; for(int i=n;i>=1;i--) if(check(i)) { ans=i; break; } printf("%d %d\n",ans,cnt); return 0; }