标签:
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 12315 | Accepted: 7189 |
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
1*2的长方形木块,问组成h*w的大长方形的种数。
从第 i行放一个小木块后,可能会对下一行造成影响,但最多只会影响到下一层。
dp[i][j]代表第当1到i-1行铺满后,第i行为状态j的种数。状态j为每一行的二进制压缩1代表存在了木块,0代表不存在。在第i行遍历所有的j,对每一个状态进行dfs,找到可以填满的一种情况,得到下一行的状态。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define LL __int64
LL dp[15][2100] ;
int h , w ;
void dfs(int low_i,int low_j,int k1,int k2,int i)
{
if( i == w )
{
dp[low_i+1][k2] += dp[low_i][low_j] ;
return ;
}
if( (k1 & (1<<i)) )
{
dfs(low_i,low_j,k1,k2,i+1) ;
return ;
}
dfs(low_i,low_j,k1|(1<<i),k2|(1<<i),i+1) ;
if( i+1 < w && (k1&(1<<(i+1))) == 0 )
dfs(low_i,low_j,(k1|(1<<i))|( 1<<(i+1) ),k2,i+2) ;
return ;
}
int main()
{
int m , i , j ;
while( scanf("%d %d", &h, &w) != EOF )
{
if( h == 0 && w == 0 ) break ;
memset(dp,0,sizeof(dp)) ;
dp[1][0] = 1 ;
m = 1 << w ;
for(i = 1 ; i <= h ; i++)
{
for(j = 0 ; j < m ; j++)
{
dfs(i,j,j,0,0);
}
}
printf("%I64d\n", dp[h+1][0]) ;
}
return 0;
}
poj2411--Mondriaan's Dream(状压dp+dfs)
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/43493069