状压dp Mondriaan's Dream

来源:互联网 发布:windows一直在准备配置 编辑:程序博客网 时间:2024/06/05 18:19

题目地址

题目大意:h*w的矩形,用1*2的矩形铺满,求不同的铺法

思路:乍一看的时候感觉跟楼梯的那个递归的题很像,但是这个是二维的。。又是状压dp。。就搜了题解做的,也不是很难理解吧。。

一行一行的往上放,记录对下一行的影响

dp[N][1<<M]   dp[i][j] 第i行的形状为j时的放法,放最后一行后保证不超出范围,也就是N+1行是空白的,最后输出的也就是dp[N+1][0]

代码:

#include<iostream>#include<stdio.h>#include<algorithm>#include<string.h>#include<math.h>#include<queue>#include<stack>using namespace std;long long N,M,dp[15][(1<<13)];int dfs(int x,int y,int c,int v,int num){   // cout<<x<<" "<<y<<" "<<c<<" "<<v<<" "<<num<<" "<<dp[x][y]<<endl;    if(num>=M) {dp[x+1][v]+=dp[x][y];return 0;}        dfs(x,y,c|1<<num,(c&1<<num)?v:(v|1<<num),num+1);        if(((c&1<<num)==0)&&((c&1<<(num+1))==0)&&num+1<M)            {dfs(x,y,c|1<<num|1<<num+1,v,num+2);}        return 0;}int main(){    while(~scanf("%d%d",&N,&M))    {        int i,j;        memset(dp,0,sizeof(dp));        if(N==0&&M==0) break;        dp[1][0]=1;        for(i=1;i<=N;i++)            for(j=0;j<(1<<M);j++)            {dfs(i,j,j,0,0);            //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;            }        cout<<dp[N+1][0]<<endl;    }}