POJ 2411 Mondriaan's Dream

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2411 Mondriaan's Dream相关的知识,希望对你有一定的参考价值。

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

 

以上是关于POJ 2411 Mondriaan's Dream的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2411Mondriaan's Dream(状压dp)

POJ 2411 Mondriaan's Dream

POJ 2411Mondriaan's Dream

[poj P2411] Mondriaan's Dream

poj2411 Mondriaan's Dream状压DP

poj2411 Mondriaan's Dream