poj 2411 Mondriaan's Dream 状态压缩DP

思路:1表示竖着的下半部分,0表示其他情况。

dp[i][j]表示第i行第j种状态满足的数目。

代码如下:

 

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cmath>
 6 #include<cstring>
 7 #include<vector>
 8 #define ll __int64
 9 #define pi acos(-1.0)
10 #define MAX 12
11 using namespace std;
12 ll dp[MAX][(1<<MAX)];
13 int n,m;
14 bool OK(int t)
15 {
16     t+=(1<<m);
17     int c=0;//记录位数
18     while(c<m){
19         int bit=t&-t;//记录最低位的1,如t=110,则bit=10
20         int w=0;//记录bit有多少位
21         while(bit){
22             w++;
23             c++;
24             bit>>=1;//右移
25         }
26         if(w%2==0) return 0;//如果是偶数,表示不满足
27         t>>=w;
28     }
29     return 1;
30 }
31 void solve()
32 {
33     if((n*m)%2){
34         cout<<0<<endl;
35         return;
36     }
37     dp[0][0]=1;
38     for(int i=1;i<=n;i++)
39     for(int j=0;j<(1<<m);j++){
40         dp[i][j]=0;
41         for(int k=0;k<(1<<m);k++){
42             if(!(j&k)&&OK(j|k))
43                 dp[i][j]+=dp[i-1][k];
44         }
45     }
46     cout<<dp[n][0]<<endl;
47 }
48 int main(){
49     while(cin>>n>>m){
50         if(n==0&&m==0) break;
51         if(n<m) swap(n,m);
52         memset(dp,0,sizeof(dp));
53         solve();
54     }
55     return 0;
56 }
View Code

 

 

 

 

posted @ 2013-08-06 16:13  _随心所欲_  阅读(169)  评论(0编辑  收藏  举报