标签:矩形 输出 return \n class fine 不能 状压dp 旋转
给定一个m×n的矩形网格,用1×2多米诺骨牌完全平铺。 请注意,即使一个平铺的旋转与另一个平铺相匹配,它们仍算作不同的平铺。 下面显示了一个平铺示例。 输入格式
输入包括多组数据。每组数据占一行,包含两个整数m,n(n×m≤100)。输入结束标志为文件结束符(EOF)。 输出格式
对于每组数据输出一行,输出总数。
每组数据,两个整数 \(n,m\)
对于每组数据,输出答案。
2 10
4 10
8 8
89
18061
12988816
\(n*m\leq 100\)
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
using std::vector;
LL f[120][2050];
vector<int> v[2050][11];
int n, m;
bool cant(int zt, int lim) {
int tot = 0;
for(int i = 0; i < lim; i++) {
if(zt & (1 << i)) {
if(tot & 1) return true;
tot = 0;
}
else tot++;
}
if(tot & 1) return true;
return false;
}
LL dfs(int dep, int zt) {
if(dep == n) return !zt;
if(f[dep][zt]) return f[dep][zt];
for(int i = 0; i < (int)v[zt][m].size(); i++) {
f[dep][zt] += dfs(dep + 1, v[zt][m][i]);
}
return f[dep][zt];
}
bool ok(int zt) {
for(int i = 1; i < 9; i++)
if(!(zt & (1 << i)) && (zt & (1 << (i - 1))) && (zt & (1 << (i + 1)))) return false;
return true;
}
int main() {
for(int lim = 1; lim <= 10; lim++)
for(int i = 0; i < (1 << lim); i++)
for(int j = 0; j < (1 << lim); j++) {
if((i & j) || cant(i | j, lim)) continue;
v[i][lim].push_back(j);
}
while(~scanf("%d%d", &n, &m)) {
if(m > n) std::swap(n, m);
memset(f, 0, sizeof f);
if((n * m) & 1) puts("0");
else printf("%lld\n", m == 1? (n & 1? 0 : 1) : dfs(0, 0));
}
return 0;
}
标签:矩形 输出 return \n class fine 不能 状压dp 旋转
原文地址:https://www.cnblogs.com/olinr/p/10228899.html