给定一个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;
} 
京公网安备 11010502036488号