hdu 2280 Tetris Comes Back

解法:

  状态压缩,首先注意到第三种可以用两个第五种的块代替,所以枚举状态的时候不用考虑3.

  dp[i][mask]记录第 i行状态为mask时能覆盖的最大面积,状态转移的时候直接枚举除了铺第一种砖块之外的所有状态,最后作下减法即可求出需要几个第一种砖块。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<bitset>
 5 #include<iostream>
 6 #define N 1010
 7 using namespace std;
 8 int dp[N][1<<5];
 9 int flag[N];
10 void dfs(int p,int mask1,int mask2,int c,int n){
11     if(p==5){
12         if(c>dp[n][mask2])dp[n][mask2]=c;
13         return;
14     }
15     if(p<4&&!(mask1&(1<<(p+1)))&&!(mask2&(3<<p)))
16         dfs(p+1,mask1|(1<<(p+1)),mask2|(3<<p),c+3,n);
17     if(p<4&&!(mask1&(1<<p))&&!(mask2&(3<<p)))
18         dfs(p+1,mask1|(1<<p),mask2|(3<<p),c+3,n);
19     if(p<4&&!(mask1&(3<<p))&&!(mask2&(1<<(p+1))))
20         dfs(p+1,mask1|(3<<p),mask2|(1<<(p+1)),c+3,n);
21     if(p<4&&!(mask1&(3<<p))&&!(mask2&(1<<p)))
22         dfs(p+1,mask1|(3<<p),mask2|(1<<p),c+3,n);
23     if(!(mask1&(1<<p))&&!(mask2&(1<<p)))
24         dfs(p+1,mask1|(1<<p),mask2|(1<<p),c+2,n);
25     if(p<4&&!(mask2&(3<<p)))
26         dfs(p+1,mask1,mask2|(3<<p),c+2,n);
27     dfs(p+1,mask1,mask2,c,n);
28 }
29 void dfs_2(int p,int mask,int c,int n){
30     if(p==4){
31         if(c>dp[n][mask])dp[n][mask]=c;
32         return;
33     }
34     if(!(mask&(3<<p)))
35         dfs_2(p+1,mask|(3<<p),c+2,n);
36     dfs_2(p+1,mask,c,n);
37 }
38 int main(){
39     int n,c;
40     char s[N];
41     while(~scanf("%d%d",&n,&c)){
42         int sum=n*5;
43         for(int i=0;i<n;i++){
44             scanf("%s",s);
45             flag[i]=0;
46             for(int j=0;j<5;j++)
47                 if(s[j]=='1'){
48                     flag[i]|=1<<j;
49                     sum--;
50                 }
51         }
52         memset(dp,-1,sizeof(dp));
53         dp[0][flag[0]]=0;
54         dfs_2(0,flag[0],0,0);
55         for(int i=0;i<n-1;i++){
56             for(int j=0;j<(1<<5);j++){
57                 if(dp[i][j]>=0){
58                 dfs(0,j,flag[i+1],dp[i][j],i+1);
59                 }
60             }
61         }
62         int maxn=0;
63         for(int i=0;i<(1<<5);i++)
64             maxn=max(maxn,dp[n-1][i]);
65         int res=sum-maxn;
66         if(res>c)puts("NO");
67         else puts("YES");
68     }
69     return 0;
70 }

 

posted @ 2013-03-15 19:48  silver__bullet  阅读(204)  评论(0编辑  收藏  举报