// 题意:一个n*m的矩阵,求用I型(1 * 2)和L型的两种方块进行填满有多少种方法
// 方法:这题和poj2411有点类似 做过方块填充的应该都认得出来要用状压
// 但是要比poj2411复杂 思路也是类似 不过因为要考虑L型 情况也复杂的多
// 语文有点不太好 可能有点说不清楚
// 利用两个参数 b1 表示前面的放置方式对now(当前行状态)的当前列的影响,b2 表示对pre(上一行状态)的当前列的影响
// 有影响为1 没影响为0 其实可以这么理解 如果为1就代表有方块从左边凸出来会占用当前列 为0就代表没有凸出来
// 这里我提出一些自己遇到的问题
// 首先枚举当前状态和上一状态要分成两种情况考虑
// 不仅要考虑b1,b2 还要考虑从下往下凸出来的这种情况,就是上一行的上一行有方块凸下来占用上一行 说起来有点绕
// 举个例子 如果当前 b1 == 0 && b2 == 0
// 那么这一列我们可以这么放
// 1 1 1 1 1 1
// 或者 或者 或者 (这四种是上一行的上一行没有从上往下凸出来的方块的放置方法)
// 1 1 1 1 1
// 1
// 或者 或者 不放 (这三种是上一行的上一行有从上往下凸出来的方块的放置方法)
// 1 1 1 1
// 上面总共7种 上面的每种都满足把上一行的当前列填满了 只不过是分为是由左边凸出来的 和 上面凸出来的
// 填满我起初也有疑问为什么下面的这三种放置也可以
// 语文果然不太好 看下面几张图一定有用
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int n, m;
long long ans[10][10];
long long dp[10][1<<10];
// 一 二 三 四 五 六
// 1 1 1 1 1 1 1
// 1 1 1 1 1 1 1 1 1
void dfs(int line, int k, int now, int pre, int b1, int b2)
{
if(k == m){
if(!b1 && !b2) dp[line][now] += dp[line - 1][pre];
return;
}
if(!b1 && !b2){
dfs(line, k + 1, now<<1|1, pre<<1, 0, 0); // 第一种方法放置
dfs(line, k + 1, now<<1|1, pre<<1, 1, 0); // 第二种方法放置
dfs(line, k + 1, now<<1|1, pre<<1, 0, 1); // 第三种方法放置
dfs(line, k + 1, now<<1|b1, pre<<1, 1, 1); // 第五种方法放置
dfs(line, k + 1, now<<1|1, pre<<1|1, 1, 1); // pre当前位的1是从上向下凸出来的 第四种方法放置
dfs(line, k + 1, now<<1|1, pre<<1|1, 1, 0); // pre当前位的1是从上向下凸出来的 第六种方法放置
dfs(line, k + 1, now<<1|0, pre<<1|1, 0, 0); // 当前位置不放
}
else if( b1 && !b2)
{
dfs(line, k + 1, now<<1|1, pre<<1, 1, 1); // 第五种方法放置
dfs(line, k + 1, now<<1|1, pre<<1|1, 0, 0); // pre当前位的1是从上向下凸出来的
}
else if(!b1 && b2)
{
dfs(line, k + 1, now<<1|1, pre<<1, 1, 1); // 第四种方法放置
dfs(line, k + 1, now<<1|1, pre<<1, 1, 0); // 第六种方法放置
dfs(line, k + 1, now<<1, pre<<1, 0, 0); // 当前位置不放
}
else{
dfs(line, k + 1, now<<1|1, pre<<1, 0, 0); // 因为b1和b2都为1 所以直接跳到下一行
}
}
int main()
{
memset(ans, 0, sizeof ans);
memset(dp, 0, sizeof dp);
while(cin>>n>>m)
{
if(ans[n][m]){
cout<<ans<<endl;
continue;
}
if(n < m)
swap(n, m);
dp[0][(1<<m) - 1] = 1;
for(int i = 1; i <= n; i++)
dfs(i, 0, 0, 0, 0, 0);
ans[n][m] = ans[m][n] = dp[n][(1<<m) - 1];
cout<<ans[n][m]<<endl;
}
return 0;
}