HDU
来源:互联网 发布:云计算行业发展 编辑:程序博客网 时间:2024/06/03 21:58
Tetris Comes Back
Problem Description
Working in corporation is toilsome and rest is important. In leisure time, WisKey like to play Tetris. The Tetris game in board is N*5, and there are 8 kinds of blocks.
Look that, red mean the area can’t be place. Other colors mean different kinds of blocks. If I give you C grey blocks (the 1st kind), and other infinite color blocks, Can you fulfil the board without any blocks overlap.
Look that, red mean the area can’t be place. Other colors mean different kinds of blocks. If I give you C grey blocks (the 1st kind), and other infinite color blocks, Can you fulfil the board without any blocks overlap.
Input
Each case will contain two integers N (1<=N<=1000) and C (0<=C<=100).
N*5 grid follow it. The ‘1’ represent red area, it can’t be place. The ‘0’ represent normal area.
Process cases to end of file.
N*5 grid follow it. The ‘1’ represent red area, it can’t be place. The ‘0’ represent normal area.
Process cases to end of file.
Output
If you can full of the Tetris, print “YES”, otherwise, print “NO”.
Sample Input
1 1000001 1001001 1010104 110000001011001000000
Sample Output
YESYESNOYES
题意:给你C个1*1的棋子,和无数个如图的2345678的棋子,问你能否拼成N*5大小的棋盘。其中棋盘有一些地方已经被填了。
解题思路:有点小激动,第一次靠自己做出了一道状压DP题。题目和SGU - 131 Hardwood floor (状压DP)是一类题目,但是这题多了许多条件。我们可以用dp[i][num][state]表示能否达到在第1~i-1行填满的情况下,用了num个1*1,第i行状态为state的状态。我们遍历每一行,每种num,每种状态,通过深搜来尝试放各种棋子,要判断好每种棋子能不能放。详看代码注释。
#include<iostream>#include<deque>#include<memory.h>#include<stdio.h>#include<map>#include<string>#include<algorithm>#include<vector>#include<math.h>#include<stack>#include<queue>#include<set>#define INF 1<<29using namespace std;int dp[1005][105][1<<6];int sta[1005];//记录每一行的初始状态int h,c;// 当前行的初始状态,当前行的状态,下一行的状态,当前判断到第几列,当前是第几行,当前用了多少个1*1,初始状态是多少个1*1void dfs(int prestate,int nowstate,int nextstate,int n,int cnt,int cnum,int fnum){ //不能大于规定数量 if(cnum>c) return; //当前行填完了 if(n>=5){ dp[cnt+1][cnum][nextstate]|=dp[cnt][fnum][prestate]&1;//状态转移 return; } //如果当前行的第n列被填了,就跳过 if(((1<<n)&nowstate)!=0){ dfs(prestate,nowstate,nextstate,n+1,cnt,cnum,fnum);//下一个 return; } //用1*1去填 dfs(prestate,nowstate|(1<<n),nextstate,n+1,cnt,cnum+1,fnum); //用 | 去填 if((nextstate&(1<<n))==0){ dfs(prestate,nowstate|(1<<n),nextstate|(1<<n),n+1,cnt,cnum,fnum); } //用 |_ 去填 if(n!=0) if((nextstate&(1<<n))==0&&(nextstate&(1<<(n-1)))==0) dfs(prestate,nowstate|(1<<n),nextstate|(1<<n)|(1<<(n-1)),n+1,cnt,cnum,fnum); //用 _| 去填 if(n<4) if((nextstate&(1<<n))==0&&(nextstate&(1<<(n+1)))==0) dfs(prestate,nowstate|(1<<n),nextstate|(1<<n)|(1<<(n+1)),n+1,cnt,cnum,fnum); if(n<4&&((1<<(n+1))&nowstate)==0){ dfs(prestate,nowstate|(1<<n)|(1<<(n+1)),nextstate,n+2,cnt,cnum,fnum);//打横放 —— if((nextstate&(1<<n))==0) dfs(prestate,nowstate|(1<<n)|(1<<(n+1)),nextstate|(1<<n),n+2,cnt,cnum,fnum);//这样放 -| if((nextstate&(1<<(n+1)))==0) dfs(prestate,nowstate|(1<<n)|(1<<(n+1)),nextstate|(1<<(n+1)),n+2,cnt,cnum,fnum);//这样放 |- //放2*2 if((nextstate&(1<<n))==0&&(nextstate&(1<<(n+1)))==0) dfs(prestate,nowstate|(1<<n)|(1<<(n+1)),nextstate|(1<<n)|(1<<(n+1)),n+2,cnt,cnum,fnum); }}int main(){ while(~scanf("%d%d",&h,&c)){ memset(dp,0,sizeof(dp)); memset(sta,0,sizeof(sta)); dp[1][0][0]=1; //初始化每行的状态 char str[10]; int sss=0; for(int i=1;i<=h;i++){ scanf("%s",str); sss=0; for(int i=0;i<5;i++){ if(str[i]=='1'){ sss|=(1<<(5-i-1)); } } sta[i]=sss; } int state=1<<5; //遍历所有状态 for(int i=1;i<=h;i++){ for(int k=0;k<=c;k++) if(dp[i][k][0]==1) dp[i][k][sta[i]]=1; for(int j=0;j<state;j++){ j|=sta[i]; for(int k=0;k<=c;k++) dfs(j,j,sta[i+1],0,i,k,k); } } bool flag=0; for(int k=0;k<=c;k++) if(dp[h+1][k][0]) flag=1; if(flag) printf("YES\n"); else printf("NO\n"); } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- java JDBC连接数据库
- QGC的小问题
- 51nod 1046 A^B Mod C
- Java学习之继承与引用(一)
- poj 3304 Segments(线段与直线相交)
- HDU
- redis的安装
- 虚拟存储器(转载自上海交大)
- 1.5 c++_复合类型
- C++顺序表(实验一)
- python当中的yield函数具体如何使用
- script (HTML标签),介绍script。
- 兼容性测试,网页的设计工具
- 21. Merge Two Sorted Lists