POJ 2411 Mondriaan's Dream 状压dp

题目链接:

https://vjudge.net/contest/159644#problem/G

题意:

用1*2的砖去恰好铺满n*m的空间,有多少种方法

题解:

http://blog.csdn.net/xingyeyongheng/article/details/21692655

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 typedef long long ll;
 6 #define MS(a) memset(a,0,sizeof(a))
 7 #define MP make_pair
 8 #define PB push_back
 9 const int INF = 0x3f3f3f3f;
10 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
11 inline ll read(){
12     ll x=0,f=1;char ch=getchar();
13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
15     return x*f;
16 }
17 //////////////////////////////////////////////////////////////////////////
18 const int maxn = (1<<11)+10;
19 
20 int n,m;
21 ll cnt[maxn],dp[maxn];
22 bool mark[maxn];
23 
24 bool check(int x){
25     while(x){
26         if(x&1){
27             x >>= 1;
28             if(!(x&1)) return false;
29             x >>= 1;
30         }else {
31             x >>= 1;
32         }
33     }
34     return true;
35 }
36 
37 void init(){
38     MS(mark); MS(cnt);
39     for(int i=0; i<(1<<m); i++){
40         if(check(i))
41             cnt[i]=1,mark[i]=true;
42     }
43 }
44 
45 void DP(){
46     for(int k=2; k<=n; k++){
47         MS(dp);
48         for(int i=0; i<(1<<m); i++){ // 枚举本行的状态
49             for(int j=0; j<(1<<m); j++){  // 枚举上一行的状态,找到可以转移到第i行的状态
50                 if((i|j) != (1<<m)-1) continue;
51                 if(!mark[i&j]) continue;
52                 dp[i] += cnt[j]; //i可以从j到达,则增加j的方案数
53 // mark[i&j] 是为了判断两行都是横着放的状态--->  1 1
54 //                                               1 1
55 // 如果是 i = 00110011
56 //        j = 11011111  i&j=00010011 这是不合法的
57 
58             }
59         }
60         for(int i=0; i<(1<<m); i++) cnt[i] = dp[i];
61     }
62 }
63 
64 int main(){
65     while(cin>>n>>m && (n+m)){
66         if(n<m) swap(n,m); //始终保持m<n,提高效率   
67         init();
68         DP();
69 
70         cout << cnt[(1<<m)-1] << endl; //输出最后一行到达时的状态必须全部是1
71     }
72 
73     return 0;
74 }
75 // http://blog.csdn.net/xingyeyongheng/article/details/21692655
原文地址:https://www.cnblogs.com/yxg123123/p/6827555.html