291. 蒙德里安的梦想【状压DP】(POJ 2411)

描述

求把N*M的棋盘分割成若干个1*2的的长方形,有多少种方案。

例如当N=2,M=4时,共有5种方案。当N=2,M=3时,共有3种方案。

如下图所示:

2411_1.jpg

输入格式

输入包含多组测试用例。

每组测试用例占一行,包含两个整数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
", 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
", dp[h][ed]);
    }
    return (0);
}
 
原文地址:https://www.cnblogs.com/llke/p/10780077.html