poj 2441 Mondriaan's Dream
转自:http://blog.csdn.net/wmn_wmn/article/details/7773167
博主的文章分析的很清楚了,这个题很明显是根据上层的状态转移到下层的状态,都是用状态压缩但是究竟何种状态才能转移到下层的何种状态时这个题目的难点,满足的状态转移的条件就是上层必须全部填满才能转移到下层,博主用的dfs()实现的真的很巧妙
#include <iostream> #include <cstring> #include <cstdio> using namespace std; #define CLR(arr,val) memset(arr,val,sizeof(arr)) const int N=15; typedef long long ll; ll dp[N][2500],ans[N][N]; int row,col; void init(int num,int id) { if(id==col){ dp[0][num]++; return; } if(id<col) init(num<<1,id+1); if(id+1<col) init(num<<2|3,id+2); } void dfs(int x,int xstate,int upstate,int id) { if(id>=col){ dp[x][xstate]+=dp[x-1][upstate]; return; } dfs(x,xstate<<1,upstate<<1|1,id+1); dfs(x,xstate<<1|1,upstate<<1,id+1); if(id+1<col) dfs(x,xstate<<2|3,upstate<<2|3,id+2); } int main() { CLR(ans,-1); while(scanf("%d%d",&row,&col)&&row&&col) { if(ans[row][col]!=-1){ printf("%lld\n",ans[row][col]); continue; } if((row*col)%2){ printf("0\n"); continue; } if(col>row) swap(col,row); CLR(dp,0); init(0,0); for(int i=1;i<row;i++) dfs(i,0,0,0); ans[row][col]=ans[col][row]=dp[row-1][(1<<col)-1]; printf("%lld\n",ans[row][col]); } return 0; }