| 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