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 }