①每个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 }
原文地址:https://www.cnblogs.com/fudanxi/p/12231006.html
时间: 2024-11-09 09:59:10