用二维数组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]);
    }
}