usaco Broken Necklace(dp)
/* ID: modengd1 PROG: beads LANG: C++ */ #include <iostream> #include <stdio.h> #include <memory.h> using namespace std; int N; char input[355]; int dp1[355],dp2[355];//dp1是以i为右端点的最长颜色相同的珠宝个数,dp2是以i为左端点的最长颜色相同的珠宝个数 void slove() { dp1[0]=1; int sumw; char flag; if(input[0]=='w') { sumw=1; flag='w'; } else { sumw=0; flag=input[0]; } bool iscicle=false; for(int i=1;i<N+N;i++) { if(input[i%N]=='w') { sumw++; dp1[i%N]=dp1[(i-1)%N]+1; } else { if(flag=='w'||flag==input[i%N])//标记为白色或者标记与此宝石颜色相同 dp1[i%N]=dp1[(i-1)%N]+1; else//标记与此宝石颜色不相同则为前面的白色珠宝的个数加上此珠宝 dp1[i%N]=1+sumw; flag=input[i%N]; sumw=0; } if(dp1[i%N]>=N)//因为可能出现全串都颜色(只有白色和另外一种颜色)一样。 { cout<<N<<endl; return; } } //刚才的操作从右往左再做一遍 dp2[N-1]=1; if(input[N-1]=='w') { sumw=1; flag=0; } else { sumw=0; flag=input[N-1]; } for(int i=(N-1)+(N-1);i>=0;i--) { if(input[i%N]=='w') { sumw++; dp2[i%N]=dp2[(i+1)%N]+1; } else { if(flag=='w'||flag==input[i%N]) dp2[i%N]=dp2[(i+1)%N]+1; else dp2[i%N]=1+sumw; flag=input[i%N]; sumw=0;//白色清空 } if(dp1[i%N]>=N) { cout<<N<<endl; return; } } int ans=0; for(int i=0;i<=N+N;i++) { if(dp1[i%N]+dp2[(i+1)%N]>ans) { ans=dp1[i%N]+dp2[(i+1)%N]; } } //可能存在此串都能被收集的情况,此时会出现ans>N if(ans>N) ans=N; cout<<ans<<endl; } int main() { freopen("beads.in","r",stdin); freopen("beads.out","w",stdout); while(~scanf("%d",&N)) { getchar(); for(int i=0;i<N;i++) { scanf("%c",&input[i]); } slove(); } return 0; }