poj 2411 动态规划 状态压缩
题意:用1*2的矩形,覆盖m*n的大矩形,问有多少种情况。
long long dp[30][1<<12],b[30][1<<12],width,height; //用int出错 long long solve(int i,int j,int pos,int state){ //第i行初始状态为j if(b[i][state])return dp[i][state]; if(pos==width){ if(i<=height){ int s=~j&((1<<width)-1); dp[i][state]+=solve(i+1,s,0,s); } return 0; } solve(i,j,pos+1,state);//第pos列不放 if(pos<=width-2&&!(j&1<<pos)&&!(j&1<<(pos+1)))//还有两列没放,并且没因上一行没放而必须竖放 solve(i,j|1<<pos|1<<(pos+1),pos+2,state);//横放 if(!pos)b[i][state]=1; return dp[i][state]; } int main(){ while(cin>>height>>width,height){ memset(b,0,sizeof(b)); memset(dp,0,sizeof(dp)); dp[height+1][0]=1; cout<<solve(1,0,0,0)<<endl; } return 0; } /* long long dp[30][1<<12],width,height,cnt; void solve(int i,int j,int pos){ //第i行初始状态为j,有cnt种方法 if(pos==width){dp[i][j]+=cnt;return;} //第i行放完,终态j的情况+cnt solve(i,j,pos+1);//第pos列不放 if(pos<=width-2&&!(j&1<<pos)&&!(j&1<<(pos+1)))//还有两列没放,并且没因上一行没放而必须竖放 solve(i,j|1<<pos|1<<(pos+1),pos+2);//横放 } int main(){ while(cin>>height>>width,height){ memset(dp,0,sizeof(dp));cnt=1; solve(1,0,0); for(int i=2;i<=height;i++) for(int j=0;j<1<<width;j++) if(dp[i-1][j]){ cnt=dp[i-1][j]; solve(i,~j&((1<<width)-1),0); } cout<<dp[height][(1<<width)-1]<<endl; } return 0; }*/