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

 

 

 

 

你可能感兴趣的:(poj)