题意
给定一个 n * m 的矩形.
问有多少种多米诺骨牌覆盖.
n, m <= 11 .
实现
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 6 #define LL long long 7 inline int rd(void) { 8 int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1; 9 int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f; 10 } 11 12 bool Legal(int s, int t, int m) { 13 F(i, 0, m-1) 14 if (!(s >> i & 1)) { 15 if (!(t >> i & 1)) 16 return false; 17 else t ^= 1<<i; 18 } 19 F(i, 0, m-1) 20 if (t >> i & 1) { 21 if (i == m-1 || !(t >> i+1 & 1)) 22 return false; 23 else i++; 24 } 25 return true; 26 } 27 28 int main(void) { 29 #ifndef ONLINE_JUDGE 30 freopen("poj2411.in", "r", stdin); 31 #endif 32 33 for (int n = rd(), m = rd(); n != 0 || m != 0; n = rd(), m = rd()) { 34 if ((n&1) && (m&1)) { puts("0"); continue; } 35 36 static int Go[2048][2048]; 37 F(s, 0, (1<<m)-1) { 38 Go[s][0] = 0; 39 F(t, 0, (1<<m)-1) 40 if (Legal(s, t, m)) 41 Go[s][++Go[s][0]] = t; 42 } 43 44 static LL f[12][2048]; 45 memset(f, 0, sizeof f), f[0][(1<<m)-1] = 1; 46 F(i, 0, n-1) F(s, 0, (1<<m)-1) if (f[i][s] != 0) 47 for (int *t = Go[s]+1; t <= Go[s]+Go[s][0]; t++) 48 f[i+1][*t] += f[i][s]; 49 printf("%lld\n", f[n][(1<<m)-1]); 50 } 51 52 return 0; 53 }
[POJ 2411] Mondriaan's Dream 状态压缩DP
时间: 2024-10-11 20:53:59