1. 程式人生 > >[SCOI2009]粉刷匠の思路

[SCOI2009]粉刷匠の思路

using -- 不變 clas min sin eof sca style

emm.dp真的是寫不來啊難過

不邊寫邊註釋我就掛了

 1  1 #include<cstdio>
 2  2 #include<cstring>
 3  3 #include<iostream>
 4  4 #include<algorithm>
 5  5 using namespace std;
 6  6 int f[55][2510],g[55][55],c[55]/*為第n行需要改變的次數就是顏色變了的次數*/,dp[2510],crt[55][2510];
 7  7 int n,m,t;
 8  8 int main()
 9  9 {
10 10 int i,j,k,l; 11 11 scanf("%d%d%d",&n,&m,&t); 12 12 memset(c,0,sizeof(c)); 13 13 for(i=1;i<=n;i++) 14 14 for(j=1;j<=m;j++) 15 15 { 16 16 scanf("%1d",&g[i][j]); 17 17 if(j==1||g[i][j]!=g[i][j-1])c[i]++;//換新一行或顏色改變時 18 18
} 19 19 for(l=1;l<=n;l++)//枚舉行數 20 20 { 21 21 memset(f,0,sizeof(f)); 22 22 for(i=1;i<=m;i++)//枚舉每前i個數的情況 23 23 for(j=1;j<=c[l];j++)//該行改變j次時(最多只需要改變mx[l]次!! 24 24 { 25 25 int sum=0; 26 26 for(k=i;k>=j;k--)
27 27 { 28 28 if(g[l][k]==g[l][i])sum++;//i和k顏色相同sum++ 29 29 f[i][j]=max(f[i][j],f[k-1][j-1]+sum);//前k個數在不變色的情況下再塗k~i,同色!加上顏色相同的r個即可 30 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 31 // 總之 就是保留之前的那個最優狀態,或是有更優狀態更新!! 32 32 } 33 33 crt[l][j]=max(crt[l][j],f[i][j]);//找出改行每算一段中最多正確的格子數 34 34 } 35 35 } 36 36 //然後,顯而易見的背包 37 37 for(k=1;k<=n;k++) 38 38 for(i=t;i>=1;i--) 39 39 for(j=1;j<=min(c[k],i);j++) 40 40 { 41 41 dp[i]=max(dp[i],dp[i-j]+crt[k][j]); 42 42 } 43 43 printf("%d",dp[t]); 44 44 return 0; 45 45 } 46

[SCOI2009]粉刷匠の思路