30 ACwing 291 蒙德里安的梦想 题解

蒙德里安的梦想

题面

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

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

2411_1.jpg|

\(1 \le N, M \le 11\)

题解

可以先转化一下题意,其实可以转化为放横着方块的合法方案数,如果横着的方块已经放好了,那么要将整个棋盘填满,放竖着的方块也只有一种方案

那么考虑两个问题

怎么判断一个已经放好横块的棋盘是否合法,怎么放横块?

我们放好横块后,只需要对于每一列看连续空格的个数是否都是偶数即可

可以这样放横块,设 \(f(i,j)\) 表示已经放好了前 \(i - 1\) 列,从 \(i - 1\) 列到第 \(i\) 列的横块的集合为 \(j\) 的方案数

因为只有 \(1 \times 2\) 的横块,所以我们只需要考虑 \(i - 2 \to i - 1\) 是如何放的,会不会影响到当前这列的状态

设当前状态为 \(j\) ,前面的状态为 \(k\) ,两个状态一定不能有交集,也就是 \(j \& k = 0\)

另外,如果 \(k, j\) 的状态都确定了,那么第 \(i - 1\) 列的状态也就确定了,又因为我们要保证每一列的连续空格数是否为偶数,所以我们还需要判断一下 \(j \mid k\) 这个状态

朴素写法是 \(O(n^24^n)\) 的,会TLE

所以我们加些预处理,具体的时间复杂度多少我也不知道,会很低

code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>

using namespace std;

typedef long long ll;

const int N = 13, M = (1 << 11) + 7;

int n, m;
ll f[N][M];
bool st[M];
vector <int> fac[M];

void solve () {
    memset (st, 0, sizeof st);
    for (int i = 0; i < (1 << n); i ++) {
        while (fac[i].size ()) fac[i].pop_back ();
    }
    //预处理出合法的匹配状态

    for (int i = 0; i < (1 << n); i ++) {
        int cnt = 0, ok = 1;
        for (int k = 0; k < n; k ++) {
            if ((i >> k) & 1) {
                if (cnt & 1) ok = 0;
                cnt = 0;
            } else {
                cnt ++;
            }
        }
        if (cnt & 1) ok = 0;
        st[i] = ok;
    }
    for (int i = 0; i < (1 << n); i ++) {
        for (int j = 0; j < (1 << n); j ++) {
            if (i & j) continue;
            if (st[i | j]) {
                fac[i].push_back (j);
            }
        }
    }

    //dp转移
    memset (f, 0, sizeof f);
    f[0][0] = 1;
    for (int i = 1; i <= m; i ++) {
        for (int j = 0; j < (1 << n); j ++) {
            for (auto k : fac[j]) {
                f[i][j] += f[i - 1][k];
            }
        }
    }
    cout << f[m][0] << endl;
}

int main () {
    while ((cin >> n >> m) && (n || m)) {
        solve ();
    }

    return 0;
}
posted @ 2025-10-05 18:10  michaele  阅读(8)  评论(0)    收藏  举报