题目链接:http://poj.org/problem?id=2411
状态压缩Dynamic Programming. For each row, at ith position, 1 means that there is a block placed at this row and next row (vertically). otherwise, its 0. For the example in question, the state of
For the example in question, the state of first row is (00100001100) binary. The state of second row is (11010010000). and so on. The state of last row must be all 0 (has no influence in next row).
We use dp[i][j] to record the number of possible ways to place row i with state j. The final answer is dp[h][0]. In the initialization, all values in dp is 0 and dp[0][0]=1. if row i with state A matches next row j with state B, dp[j][B]+=dp[i][A].
代码如下:
1 #include <iostream> 2 #include <math.h> 3 #include <stdio.h> 4 #include <cstdio> 5 #include <algorithm> 6 #include <string.h> 7 #include <string> 8 #include <sstream> 9 #include <cstring> 10 #include <queue> 11 #include <vector> 12 #include <functional> 13 #include <cmath> 14 #include <set> 15 #define SCF(a) scanf("%d", &a) 16 #define IN(a) cin>>a 17 #define FOR(i, a, b) for(int i=a;i<b;i++) 18 #define Infinity 999999999 19 typedef long long Int; 20 using namespace std; 21 22 int h, w; //1 <= h, w <= 11 23 //max states are 2^11 = 2048 24 bool match[2048][2048]; 25 Int state[12][2048]; //i -> row, j -> state 26 int states; //num of states for a row 27 28 bool check(int a, int b) 29 { 30 if (a&b) 31 return false; 32 int c = a | b; 33 int zeroCon = 0; 34 FOR(i, 0, w) 35 { 36 if (!(c & (1 << i))) 37 zeroCon++; 38 else 39 { 40 if (zeroCon % 2) 41 return false; 42 else 43 zeroCon = 0; 44 } 45 } 46 if (zeroCon % 2) 47 return false; 48 return true; 49 } 50 51 int main() 52 { 53 FOR(i, 0, 12) 54 { 55 FOR(j, 0, 2048) 56 state[i][j] = -1; 57 } 58 59 while (scanf("%d %d", &h, &w) != EOF) 60 { 61 if (h == 0 && w == 0) 62 break; 63 if ((h*w) % 2) 64 { 65 printf("0\n"); 66 continue; 67 } 68 69 if (h < w) 70 { 71 int temp = w; 72 w = h; 73 h = temp; 74 } 75 76 states = (1 << w); // 0 - states-1 77 78 FOR(i, 0, states) 79 { 80 FOR(j, 0, states) 81 { 82 match[i][j] = check(i, j); 83 } 84 } 85 86 FOR(i, 0, h + 1) 87 { 88 FOR(j, 0, states) 89 state[i][j] = 0; 90 } 91 92 state[0][0] = 1; 93 94 FOR(i, 1, h + 1) 95 { 96 FOR(si, 0, states) 97 { 98 FOR(sp, 0, states) 99 { 100 if(match[sp][si]==true) 101 state[i][si] += state[i - 1][sp]; 102 } 103 } 104 } 105 106 printf("%lld\n", state[h][0]); 107 } 108 return 0; 109 }