求把N*M的棋盘分割成若干个1*2的的长方形,有多少种方案。
例如当N=2,M=4时,共有5种方案。当N=2,M=3时,共有3种方案。
如下图所示:
输入格式
输入包含多组测试用例。
每组测试用例占一行,包含两个整数N和M。
当输入用例N=0,M=0时,表示输入终止,且该用例无需处理。
输出格式
每个测试用例输出一个结果,每个结果占一行。
数据范围
1≤N,M≤111≤N,M≤11
输入样例:
1 2
1 3
1 4
2 2
2 3
2 4
2 11
4 11
0 0
输出样例:
1
0
1
2
3
5
144
51205
题源POJ 2411
参考博客 https://blog.csdn.net/u013480600/article/details/19569291
#include <iostream>
#include <cstdio> //EOF,NULL
#include <cstring> //memset
#include <cmath> //ceil,floor,exp,log(e),log10(10),hypot(sqrt(x^2+y^2)),cbrt(sqrt(x^2+y^2+z^2))
#include <algorithm> //fill,reverse,next_permutation,__gcd,
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
using namespace std;
#define rep(i, a, n) for (int i = a; i < n; ++i)
#define sca(x) scanf("%d", &x)
#define sca2(x, y) scanf("%d%d", &x, &y)
#define sca3(x, y, z) scanf("%d%d%d", &x, &y, &z)
#define pri(x) printf("%d\n", x)
#define pb push_back
#define mp make_pair
typedef pair<int, int> P;
typedef long long ll;
const ll inf = 99999999999;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 105;
const int N = 1e4 + 5;
int t, n, m;
int cnt, ans, ed;
ll dp[15][1<<15];
int path[50000][2];
int h, w;
void dfs(int l, int now, int pre)
{
if (l > w) {
return;
}
if (l == w) {
path[cnt][0] = pre;
path[cnt++][1] = now;
return;
}
dfs(l + 2, (now << 2)|3, (pre << 2)|3); // 竖放,当前行为1,上一行为0
dfs(l + 1, (now << 1)|1, (pre << 1)); // 横放 当前行和上一行都为11
dfs(l + 1, (now << 1), (pre << 1)|1); //不放,上一行为1,当前行为0
}
int main()
{
while (sca2(h, w) && h && w)
{
if (h < w) {
swap(h, w);
}
cnt = 0;
dfs(0, 0, 0);
memset(dp, 0, sizeof dp);
ed = (1 << w) - 1;
dp[0][ed] = 1;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < cnt; j++)
{
dp[i + 1][path[j][1]] += dp[i][path[j][0]];
}
}
printf("%lld\n", dp[h][ed]);
}
return (0);
}