CodeForces 225C Barcode :一个只包含.和*的矩阵,改变最少的点+星,使每列只有一种,连续的在x-y之间 :dp
比较裸的dp了,多做dp有益身心健康==
dp[i][j][kind]表示到i时,是以kind的种类结束,且他连续了j个
这种dp一般想到状态,转移方程也就好想了,注意1才需要大规模累加
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 char s[1005][1005]; 6 int num[1005],dp[1005][1005][2]; 7 int main() 8 { 9 int n,m,x,y,i,j,l,r,tmp,kind; 10 scanf("%d%d%d%d",&n,&m,&x,&y); 11 if (y>m) y=m; 12 for (i=1;i<=n;i++) 13 { 14 scanf("%s",s[i]); 15 for (j=m;j>=1;j--) s[i][j]=s[i][j-1]; 16 } 17 for (j=1;j<=m;j++) 18 { 19 num[j]=0; 20 for (i=1;i<=n;i++) 21 if (s[i][j]=='#') num[j]++; 22 } 23 memset(dp,0x3f,sizeof(dp)); 24 for (i=0;i<=m;i++) dp[0][i][0]=dp[0][i][1]=0; 25 for (j=1;j<=m;j++) 26 for (kind=0;kind<=1;kind++) 27 for (l=1;l<=min(y,j);l++) 28 { 29 if (l==1) 30 { 31 tmp=0x3f3f3f3f; 32 for (r=x;r<=y;r++) 33 tmp=min(tmp,dp[j-1][r][1-kind]); 34 dp[j][l][kind]=tmp+(kind?n-num[j]:num[j]); 35 } 36 else dp[j][l][kind]=dp[j-1][l-1][kind]+(kind?n-num[j]:num[j]); 37 } 38 tmp=0x3f3f3f3f; 39 for (j=x;j<=y;j++) 40 tmp=min(tmp,min(dp[m][j][0],dp[m][j][1])); 41 printf("%d\n",tmp); 42 }