http://poj.org/problem?id=2411
求一个n*m矩阵用1*2方块去填满的情况有几种
思路:状压dp,先预处理那些状态之间能互相到达,情况就几种,上一个两个1,下一个状态也两个1,上一个为0,下一个必须为1,还有一种是上一个为1,下一个为0的情况
然后就一层层往后递推即可
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int n, m, g[15555][2], gn;
long long dp[2][2111];
void dfs(int len, int now, int pre) {
if (len > m) return;
if (len == m) {
g[gn][0] = pre;
g[gn++][1] = now;
return;
}
dfs(len + 2, (now<<2)|3, (pre<<2)|3);
dfs(len + 1, (now<<1)|1, pre<<1);
dfs(len + 1, now<<1, (pre<<1)|1);
}
int main() {
while (~scanf("%d%d", &n, &m) && n || m) {
if (n < m) swap(n, m);
gn = 0;
dfs(0, 0, 0);
printf("%d\n", gn);
memset(dp, 0, sizeof(dp));
dp[0][(1<<m) - 1] = 1;
for (int i = 1; i <= n; i++) {
int now = i%2;
int pre = !now;
memset(dp[now], 0, sizeof(dp[now]));
for (int j = 0; j < gn; j++) {
dp[now][g[j][1]] += dp[pre][g[j][0]];
}
}
printf("%lld\n", dp[n % 2][(1<<m) - 1]);
}
return 0;
}