BZOJ1704: [Usaco2007 Mar]Face The Right Way 自动转身机

n<=5000个数0或1,每次可以连续对固定长度区间取反,目标把所有1变0,求一个取反区间的固定长度K使取反次数最少。

答案关于K不单调,因此枚举K,对每个K扫一遍区间,遇到1就把连续K个数反转,看最后K-1个数是否在这样一番操作后都为0。为什么?不知道。

区间取反后查询,用差分。n2可过。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<math.h>
 6 //#include<iostream>
 7 using namespace std;
 8 
 9 int n;
10 #define maxn 5011
11 bool a[maxn],b[maxn];
12 char c[5];
13 int main()
14 {
15     scanf("%d",&n);
16     for (int i=1;i<=n;i++)
17     {
18         scanf("%s",c);
19         a[i]=c[0]=='B';
20     }
21     int ans=n,K=0;
22     for (int k=1;k<=n;k++)
23     {
24         bool now=0;int cnt=0;
25         memset(b,0,sizeof(b));
26         for (int i=1;i<=n-k+1;i++)
27         {
28             now^=b[i];
29             if (now^a[i])
30             {
31                 cnt++;
32                 now^=1;
33                 b[i+k]^=1;
34             }
35         }
36         bool flag=1;
37         for (int i=n-k+2;i<=n;i++)
38         {
39             now^=b[i];
40             if (a[i]^now) flag=0;
41         }
42         if (flag && cnt<ans)
43         {
44             ans=cnt;
45             K=k;
46         }
47     }
48     printf("%d %d
",K,ans);
49     return 0;
50 }
View Code
原文地址:https://www.cnblogs.com/Blue233333/p/7435294.html