您的位置:首页 > 其它

POJ2411

2015-06-30 11:33 267 查看
题目大意:一个宽w高为h的棋盘,现在要用1*2的多米诺骨牌不重叠地覆盖整个棋盘,问有多少种方案。

h<11,w<11

分析:1.h*w若为奇数,则无解。

2.按行处理。处理第i行时,保证前i-1行全部覆盖,当前行的状态为state。

以f[i][state]表示处理到第i行,第i行的状态为state,且前i-1行全部填满的方案数。

f[i][state]=∑f[i-1][state2]

需要统计有哪些state2可以转移到state。这个可以用dfs来预处理出来。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cstring>
using namespace std;
#define MAXN 2200
vector<int> arr[MAXN];
long long f[2][MAXN],h,w,n,ss;
int tt;
void find(int s,int t,int i)
{
if(s==0||i>=n){arr[ss].push_back(t);return;}
if(s&1)
{
if(s&2)
find(s>>2,t,i+2);
find(s>>1,t^(1<<i),i+1);
}
else
find(s>>1,t,i+1);
}
int main()
{
n=11;
int z=(1<<n)-1;
for(int i=0;i<=z;i++)
{
ss=i;
find(i,z,0);
}
while(scanf("%d%d",&h,&w)&&(w||h))
{
memset(f,0,sizeof f);
if(w%2&&h%2)
{printf("0\n");
continue;
}
int z1=(1<<w)-1;
f[0][z1]=1;
for(int i=1;i<=h;i++)
{
for(int j=0;j<=z1;j++)
{
f[i&1][j]=0;
for(int k=0;k<arr[j].size();k++)
{
f[i&1][j]+=f[!(i&1)][arr[j][k]&z1];
}
}
}
printf("%I64d\n",f[h&1][z1]);
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: