alwaysBeAStarter

博客园 首页 新随笔 联系 订阅 管理

题目链接: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 }

 

posted on 2017-06-23 21:45  alwaysBeAStarter  阅读(82)  评论(0编辑  收藏  举报