| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 12341 | Accepted: 7204 |
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
Source
#include <cstdio>
#include <cstring>
#define ll long long
ll dp[12][(1 << 12)];
int h, w;
bool ok(int t)
{
int cnt = 0;
for(int i = 0; i < w; i++)
{
if(t & 1)
{
if(cnt & 1) //判断相邻两个1之间0的个数
return false;
}
else
cnt++;
t >>= 1;
}
if(cnt & 1) //判断最后一个1左边0的个数
return false;
return true;
}
int main()
{
while(scanf("%d %d", &h, &w) != EOF && (w + h))
{
if((h * w) & 1) //面积为奇数不可能拼成,因为一个单位面积就为偶数了
{
printf("0\n");
continue;
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(int i = 1; i <= h; i++)
for(int j = 0; j < (1 << w); j++)
for(int k = 0; k < (1 << w); k++)
if(((k & j) == 0) && ok(k ^ j))
dp[i][j] += dp[i - 1][k];
printf("%lld\n", dp[h][0]);
}
}POJ 2411 && HDU 1400 Mondriaan's Dream (状压dp 经典题)
原文:http://blog.csdn.net/tc_to_top/article/details/43891119