标签:
Description

Input
Output
For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 times 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple times.Sample Input
1 2 1 3 1 4 2 2 2 3 2 4 2 11 4 11 0 0
Sample Output
1 0 1 2 3 5 144 51205
大意:给你行数和列数,问你总共有多少种铺地的方法,状态转移一共三种情况
(我们把竖的放的上面一个看做是0下面看做是1)
1,now&(1<<(m-1-step))) == 0 pre<<1|1 不铺
2. now&(1<<(m-2-step))) != 0 pre<<2|3 横着铺
3. 其他情况都竖着铺 pre<<1
dfs遍历所有的情况
0 1 1 1
1 1 1 0
当step == m 的时候说明全部铺满了 当前dp值只要加上上一行的dp值
被第二种坑了。。如果now&(1<<(m-2-step)) == 1 的话并不是所有的情况,因为二进制会出现11....
#include<cstdio>
#include<cstring>
#include<algorithm>
long long dp[12][2148];
int n,m;
void dfs(int step,int pre,int now,int row)
{
if(step == m){
dp[row][now] += dp[row-1][pre];
return ;
}
if((now & (1 << (m - step - 1))) == 0)
dfs(step+1,pre<<1|1,now,row);
else {
if(step + 1 == m) dfs(step+1,pre<<1,now,row);
else {
if(now & (1 << (m - step - 2)))
dfs(step+2,pre<<2|3,now,row);
dfs(step+1,pre<<1,now,row);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m)){
if( n == 0 && m == 0)
break;
memset(dp,0,sizeof(dp));
dp[0][(1<<m)-1] = 1;
for(int i = 1; i <= n ; i++)
for(int j = 0 ;j < (1 << m); j++)
dfs(0,0,j,i);
printf("%lld\n",dp[n][(1<<m)-1]);
}
return 0;
}
POJ2411——状态压缩+DFS——Mondriaan's Dream
标签:
原文地址:http://www.cnblogs.com/zero-begin/p/4482832.html