题目大意:要求在n *m的网格上面铺满2 * 1的I型砖头活着2 * 2(缺了一个1 *1)的L型砖头,问有多少中铺法
解题思路:和POJ - 2411 Mondriaan’s Dream类似
这里用s1表示上一行的状态,s2表示当前行的状态,b1表示上一行的上一列是否对当前列有影响,b2表示当前行的上一列是否对当前列有影响
可得到一张状态转换表
以上摘自这里写链接内容
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 10
#define S (1 << 12)
long long ans[N][N], dp[N][S];
int n, m;
void init() {
int t;
if (n < m) {
t = n;
n = m;
m = t;
}
memset(dp, 0, sizeof(dp));
dp[0][(1 << m) - 1] = 1;
}
void dfs(int r, int c, int s1, int s2, int b1, int b2) {
if (c == m) {
if (!b1 && !b2) {
dp[r][s2] += dp[r - 1][s1];
}
return ;
}
if (!b1 && !b2) {
dfs(r, c + 1, s1 << 1, (s2 << 1) | 1, 0, 0);
dfs(r, c + 1, s1 << 1, (s2 << 1) | 1, 1, 0);
dfs(r, c + 1, s1 << 1, (s2 << 1) | 1, 0, 1);
}
if(!b1)
dfs(r, c + 1, s1 << 1, (s2 << 1) | b2, 1, 1);
if(!b2) {
dfs(r, c + 1, (s1 << 1) | (1 - b1), (s2 << 1) | 1, 0, 1);
dfs(r, c + 1, (s1 << 1) | (1 - b1), (s2 << 1) | 1, 1, 1);
}
dfs(r, c + 1, (s1 << 1) | (1 - b1), (s2 << 1) | b2, 0, 0);
}
void solve() {
for(int i = 1; i <= n; i++)
dfs(i,0,0,0,0,0);
printf("%lld\n", ans[n][m] = ans[m][n] = dp[n][(1 << m) - 1]);
}
int main() {
memset(ans, -1, sizeof(ans));
while(scanf("%d%d", &n, &m) != EOF) {
if(ans[n][m] != -1) {
printf("%lld\n", ans[n][m]);
continue;
}
init();
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-14 09:30:32