SGU 131 Hardwood floor

来源:互联网 发布:java 局部变量是什么 编辑:程序博客网 时间:2024/05/23 18:31

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=131

题意:给出n*m(1≤n、m≤9)的方格棋盘,用1*2 的矩形的骨牌和L 形的(2*2 的去掉一个角)骨牌不重叠地覆盖,求覆盖满的方案数。


分析:覆盖模型,状态压缩DP。具体见周伟《状态压缩》。


Code:

#include <algorithm>#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <vector>#include <queue>#include <cmath>#include <map>#include <set>#define LL long long#define Max(a,b) ((a)>(b)?(a):(b))#define Min(a,b) ((a)<(b)?(a):(b))using namespace std;const int inf=0x3f3f3f3f;LL dp[2][1000];int n,m,t;void dfs(int s1,int s2,int b1,int b2,int cnt){    if(cnt>=m){        if(!b1&&!b2) dp[t][s1]+=dp[t^1][s2];        return ;    }    if(b1==0){        dfs((s1<<1)|1,(s2<<1)+1-b2,1,0,cnt+1);        dfs((s1<<1)|1,(s2<<1)+1-b2,1,1,cnt+1);        if(b2==0){            dfs((s1<<1)|1,s2<<1,0,0,cnt+1);            dfs((s1<<1)|1,s2<<1,1,0,cnt+1);            dfs((s1<<1)|1,s2<<1,0,1,cnt+1);        }    }    if(b2==0) dfs((s1<<1)+b1,s2<<1,1,1,cnt+1);    dfs((s1<<1)+b1,(s2<<1)+1-b2,0,0,cnt+1);}int main(){    while(scanf("%d %d",&n,&m)==2){        memset(dp,0,sizeof(dp));        if(n<m){n^=m;m^=n;n^=m;}        dp[0][(1<<m)-1]=1;        t=0;        for(int i=1;i<=n;i++){            t^=1;            memset(dp[t],0,sizeof(dp[0]));            dfs(0,0,0,0,0);        }        cout<<dp[t][(1<<m)-1]<<endl;    }    return 0;}