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 }