给定一个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; }