用二维数组dp,第一维表示状态,第二维表示当前行。最后输出的是最后一行全部都横着放的状态。用1表示竖着放,0表示横着放,注释详细。。。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll dp[1<<12][12];
int h,w;
bool judge(int x)//判断连续的0是不是偶数个
{
int ww=w;
int cnt=0;
while(ww--)
{
if(x&1) {
if(cnt&1) return false;
cnt=0;
}
else cnt++;
x>>=1;
}
if(cnt&1) return false;
return true;
}
int main()
{
while(scanf("%d%d",&h,&w)!=EOF)
{
if(h==0&&w==0) break;
int len=(1<<w)-1;
dp[0][0]=1;//边界
for(int r=1;r<=h;r++)
{
for(int j=0;j<=len;j++)//枚举这一行
{
if(j&&(r==h)) break;//加这行提高效率
dp[j][r]=0;
for(int i=0;i<=len;i++)//枚举上一行
{
if(i&&(r==1)) break;//加这行提高效率
if(i&j) continue;//如果两行都放竖的,不可能
if(!judge(i|j)) continue;//如果这样,无法用1x2的填充
dp[j][r]+=dp[i][r-1];//累加方案
}
}
}
printf("%lld\n",dp[0][h]);
}
}


京公网安备 11010502036488号