题意:用1*2的矩形拼成和h*w的矩形有几种拼法.(h, w <= 11)
思路:用1表示该处竖着放一块砖,用0表示横着放的砖,或者竖着放的第二行。显然同一列上下两行不能同时为1,
一行中每个未放竖的矩形区间中的0数量一定要是2的倍数。这样从第一行递推到第h行,最后答案是dp[h][0],因为前
i-1行状态确定最后一行的状态也就确定。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 12;
ll dp[maxn][1<<maxn];
int h, w;
bool judge(int x)
{
int cnt = 0;
for(int i = 0; i < w; i++)
{
if(x%2)
{
if(cnt%2) return 0; //一行中区间未标记的数量一定要是2的倍数
}
else cnt++;
x /= 2;
}
if(cnt%2) return 0;
else return 1;
}
int main(void)
{
while(cin >> h >> w)
{
if(!h && !w) break;
if(w*h%2) { puts("0"); continue; }
if(w > h) swap(w, h);
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
int tot = 1<<w;
for(int i = 1; i <= h; i++)
for(int j = 0; j < tot; j++)
for(int k = 0; k < tot; k++)
if(!(j&k)&&judge(j^k)) //j^k上一行的列铺了竖着的,这一行这列标记1
dp[i][j] += dp[i-1][k];
printf("%lld\n", dp[h][0]);
}
return 0;
}