题目链接:http://poj.org/problem?id=2411
题意:给出一个h*w的矩形,问用1*2的方块将其完全填充的不同方式有多少种。
h,w范围很小,可用2进制来表示每一行当前的填充状态,然后由前一行状态判断当前行状态是否合法
dp[l][i] =sigama(dp[l-1][j]);
其中i为当前行状态,j为前一行状态.
比较重要的两个位运算
i|j 获取前行与些行的并,看是否满足使前一行填满。
i&j 获取当前行的横放情况,可进一步判断是否合法。
#include<stdio.h>
#include<string.h>
#define M 16
#define N 4056
__int64 dp[M][N];
short h,w;
short total;
bool Fail(int x)
{
while(x){
if(x&1){
if(x&2) x>>=2;
else return true;
}
else x>>=1;
}
return false;
}
int main()
{
short l,i,j;
while(scanf("%d%d",&h,&w),h|w){
if((h*w)&1) {puts("0");continue;}
if(h<w){h=h^w;w=h^w;h=h^w;}
total=1<<w;
memset(dp,0,sizeof(dp));
dp[0][total-1]=1;
for(l=1;l<=h;l++){
for(i=0;i<total;i++){
for(j=0;j<total;j++){
if(!dp[l-1][j]) continue;
if((i|j)!=total-1) continue;
if(Fail(i&j)) continue;
dp[l][i]+=dp[l-1][j];
}
}
}
printf("%I64d\n",dp[h][total-1]);
}
return 0;
}