1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 int f[55][2510],g[55][55],c[55]/*为第n行需要改变的次数就是颜色变了的次数*/,dp[2510],crt[55][2510]; 7 int n,m,t; 8 int main() 9 { 10 int i,j,k,l; 11 scanf("%d%d%d",&n,&m,&t); 12 memset(c,0,sizeof(c)); 13 for(i=1;i<=n;i++) 14 for(j=1;j<=m;j++) 15 { 16 scanf("%1d",&g[i][j]); 17 if(j==1||g[i][j]!=g[i][j-1])c[i]++;//换新一行或颜色改变时 18 } 19 for(l=1;l<=n;l++)//枚举行数 20 { 21 memset(f,0,sizeof(f)); 22 for(i=1;i<=m;i++)//枚举每前i个数的情况 23 for(j=1;j<=c[l];j++)//该行改变j次时(最多只需要改变mx[l]次!! 24 { 25 int sum=0; 26 for(k=i;k>=j;k--) 27 { 28 if(g[l][k]==g[l][i])sum++;//i和k颜色相同sum++ 29 f[i][j]=max(f[i][j],f[k-1][j-1]+sum);//前k个数在不变色的情况下再涂k~i,同色!加上颜色相同的r个即可 30 f[i][j]=max(f[i][j],f[k-1][j-1]+i-k+1-sum); //前k个数在不变色的时候再涂k~i,不同色时,总共有(i-k+1)个格子,r个不同色!!加上(i-k+1-r)即为同色!! 31 // 总之 就是保留之前的那个最优状态,或是有更优状态更新!! 32 } 33 crt[l][j]=max(crt[l][j],f[i][j]);//找出改行每算一段中最多正确的格子数 34 } 35 } 36 //然后,显而易见的背包 37 for(k=1;k<=n;k++) 38 for(i=t;i>=1;i--) 39 for(j=1;j<=min(c[k],i);j++) 40 { 41 dp[i]=max(dp[i],dp[i-j]+crt[k][j]); 42 } 43 printf("%d",dp[t]); 44 return 0; 45 }
[SCOI2009]粉刷匠の思路
猜你喜欢
转载自www.cnblogs.com/pile8852/p/9275450.html
今日推荐
周排行