给定一个2×n的棋盘,可以对上面的格子黑白染色,求染色后棋盘上的联通块的个数正好为k的染色方案数。

0:表示00
1:表示11
2:表示10
3:表示01
dp[i][j][k] 表示第i个位置用j状态是有k个联通块的数量
然后枚举当前位置的状态与前一个的状态形成的联通块的数量

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2005;
const int mod = 998244353;
int dp[maxn][4][maxn];
/*
0:00
1:11
2:10
3:01
*/
// 1:01 02, 03
int main() {
    int n, m;
    cin >> n >> m;

    dp[1][0][1] = 1;
    dp[1][1][1] = 1;
    dp[1][2][2] = 1;
    dp[1][3][2] = 1;

    for (int i = 2; i <= n; i++) {
        for (int j = 0; j <= 3; j++) { //当前位置 
            for (int k = 0; k <= 3; k++) { //上一个位置 
                for (int v = 1; v <= m; v++) {
                    if (j == k || ((j == 1 || j == 0) && (k == 2 || k == 3))) {
                        dp[i][j][v] = (dp[i][j][v] + dp[i - 1][k][v]) % mod;
                    } else if (j + k == 5) {
                        dp[i][j][v + 2] = (dp[i][j][v + 2] + dp[i - 1][k][v]) % mod;
                    } else {
                        dp[i][j][v + 1] = (dp[i][j][v + 1] + dp[i - 1][k][v]) % mod;
                    }
                }
            }
        }
    }
    int ans = 0;
    for (int i = 0; i <= 3; i++) {
        ans = (ans + dp[n][i][m]) % mod;
    }
    cout << ans << endl;
    return 0;
}