①每个K从最左边进行考虑
②f[i]=[i,i+k-1]是否进行反转:1代表是,0代表否
③∑ (i)(i=i+1-K+1) f[j]=∑ (i-1)(i=i-K+1) f[j]+f[i]-f[i-K+1]
1 #include<cstdio>
2 #include<iostream>
3 #include<algorithm>
4 #include<queue>
5 #include<map>
6 #include<vector>
7 #include<set>
8 #include<string>
9 #include<cmath>
10 #include<cstring>
11 using namespace std;
12 int n;
13 int dir[5005],f[5005];//dir牛的方向0F1B,f是[i,i-k+1]是否反转
14 int cal(int k)//k求最小操作数
15 {
16 memset(f,0,sizeof(f));
17 int res=0;
18 int sum=0;//f的和
19 for(int i=0;i+k<=n;i++)
20 {
21 if((dir[i]+sum)%2!=0)
22 {
23 res++;
24 f[i]=1;
25 }
26 sum+=f[i];
27 if(i-k+1>=0)
28 {
29 sum-=f[i-k+1];
30 }
31 }
32 //检查后面的牛有没有朝后
33 for(int i=n-k+1;i<n;i++)
34 {
35 if((dir[i]+sum)%2!=0)
36 {
37 return -1;//无解
38 }
39 if(i-k+1>=0)
40 {
41 sum-=f[i-k+1];
42 }
43 }
44 return res;
45 }
46 void solve()
47 {
48 int resK=1,resM=n;
49 for(int k=1;k<=n;k++)
50 {
51 int m=cal(k);
52 if(m>=0&&resM>m)
53 {
54 resM=m;
55 resK=k;
56 }
57 }
58 printf("%d %d\n",resK,resM);
59 }
60 int main()
61 {
62 scanf("%d",&n);
63 for(int i=0;i<n;i++)
64 {
65 getchar();
66 char c=getchar();
67 if(c=='B')
68 dir[i]=1;
69 else
70 dir[i]=0;
71 }
72 solve();
73 return 0;
74 }