您的位置:首页 > 其它

SGU - 131 Hardwood floor (状压DP)

2017-09-20 11:28 387 查看


131. Hardwood floor

time limit per test: 0.25 sec.

memory limit per test: 4096 KB

The banquet hall of Computer Scientists' Palace has a rectangular form of the size M x N (1<=M<=9, 1<=N<=9). It is necessary to lay hardwood floors in the hall. There are wood pieces of two forms:

1) rectangles (2x1)

2) corners (squares 2x2 without one 1x1 square)

You have to determine X - the number of ways to cover the banquet hall.

Remarks. The number of pieces is large enough. It is not allowed to leave empty places, or to cover any part of a surface twice, or to saw pieces.

Input
The first line contains natural number M. The second line contains a natural number N.

Output
First line should contain the number X, or 0 if there are no solutions.

Sample Input

2 3


Sample Output

5

Author: Herman "Smash" Narkaytis, Paul "Stingray" Komkoff
Resource: 5th Southern Subregional Contest. Saratov 2002
Date: 2002-10-10
题意:给你无数个2*1和L型积木(2*2缺一个角),问你平成M*N大小的矩形棋盘有多少种拼法。

解题思路:跟这题做法一模一样,只是深搜时判断条件多了。要好好记住这类题的做法!http://blog.csdn.net/lzc504603913/article/details/77994832

#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<<29
using namespace std;
typedef long long int ll;

ll dp[15][1<<12];
int h,w;

void dfs(int prestate,int nowstate,int nextstate,int n,int cnt){

if(n>=w){
dp[cnt+1][nextstate]+=dp[cnt][prestate];
return;
}

if(((1<<n)&nowstate)!=0){
dfs(prestate,nowstate,nextstate,n+1,cnt);//下一个
return;
}

if((nextstate&(1<<n))==0)//如果 2*1 可以竖着放
dfs(prestate,nowstate|(1<<n),nextstate|(1<<n),n+1,cnt);

if(n!=0)//如果L 可以 _| 这样插进去
if((nextstate&(1<<n))==0&&(nextstate&(1<<(n-1)))==0)
dfs(prestate,nowstate|(1<<n),nextstate|(1<<n)|(1<<(n-1)),n+1,cnt);

if(n<w-1)//如果L 可以 |_ 这样插进去
if((nextstate&(1<<n))==0&&(nextstate&(1<<(n+1)))==0)
dfs(prestate,nowstate|(1<<n),nextstate|(1<<n)|(1<<(n+1)),n+1,cnt);

if(n+1<w&&((1<<(n+1))&nowstate)==0){
dfs(prestate,nowstate|(1<<n)|(1<<(n+1)),nextstate,n+2,cnt);//2*1 横着放

if((nextstate&(1<<n))==0)//如果L 可以 |~ 这样插进去
dfs(prestate,nowstate|(1<<n)|(1<<(n+1)),nextstate|(1<<n),n+2,cnt);

if((nextstate&(1<<(n+1)))==0)//如果L 可以 ~| 这样插进去
dfs(prestate,nowstate|(1<<n)|(1<<(n+1)),nextstate|(1<<(n+1)),n+2,cnt);
}

}

int main(){

while(~scanf("%d%d",&h,&w)){

memset(dp,0,sizeof(dp));
dp[1][0]=1;

int state=1<<w;

for(int i=1;i<=h;i++)
for(int j=0;j<state;j++)
dfs(j,j,0,0,i);

printf("%lld\n",dp[h+1][0]);

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: