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 }
View Code

题目链接:http://codeforces.com/problemset/problem/225/C

posted on 2015-03-27 16:07  xiao_xin  阅读(216)  评论(0编辑  收藏  举报

导航