UVA11270 Tiling Dominoes

\(\color{#0066ff}{ 题目描述 }\)

给定一个m×n的矩形网格,用1×2多米诺骨牌完全平铺。 请注意,即使一个平铺的旋转与另一个平铺相匹配,它们仍算作不同的平铺。 下面显示了一个平铺示例。 输入格式

输入包括多组数据。每组数据占一行,包含两个整数m,n(n×m≤100)。输入结束标志为文件结束符(EOF)。 输出格式

对于每组数据输出一行,输出总数。

\(\color{#0066ff}{输入格式}\)

每组数据,两个整数 \(n,m\)

\(\color{#0066ff}{输出格式}\)

对于每组数据,输出答案。

\(\color{#0066ff}{输入样例}\)

2 10
4 10
8 8

\(\color{#0066ff}{输出样例}\)

89
18061
12988816

\(\color{#0066ff}{数据范围与提示}\)

\(n*m\leq 100\)

\(\color{#0066ff}{ 题解 }\)

一个状压DP,也可以写插头DP蒟蒻目前还不会

可以发现,行或列其中一个一定不超过10,所以将其状压

横着的块均为0, 竖着的块,上面为1, 下面为0

因此,如果上一行的某位置为1,那么本行该位置必须为0, 代表竖着块的下半部分

最后一行的状态必须为0

如何判断一个状态能否作为某状态的下一行

首先,对于横着的块,肯定是成对出现的,但是如果上一行是1,那么对应本行的0是属于竖着的块的,是独立的,不能与旁边的0拼成横着的

可以发现,将它们进行按位或,那么那些特殊的0就成了1, 这时候判断一下每次连续的0是否有偶数个就行了

对于上面是1下面必须是0的问题,可以按位与一下,为0就行了

为了保证时间复杂度,与处理出合法拼接状态,就能过了

#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;
}
posted @ 2019-01-06 14:38  olinr  阅读(161)  评论(0编辑  收藏  举报