Bicolorings
You are given a grid, consisting of 2 2 2 rows and n n n columns. Each cell of this grid should be colored either black or white.
Two cells are considered neighbours if they have a common border and share the same color. Two cells A A A and B B B belong to the same component if they are neighbours, or if there is a neighbour of A A A that belongs to the same component with B B B.
Let’s call some bicoloring beautiful if it has exactly k k k components.
Count the number of beautiful bicolorings. The number can be big enough, so print the answer modulo 998244353 998244353 998244353.
Input
The only line contains two integers n n n and k k k ( 1 ≤ n ≤ 1000 1 \le n \le 1000 1≤n≤1000, 1 ≤ k ≤ 2 n 1 \le k \le 2n 1≤k≤2n) — the number of columns in a grid and the number of components required.
Output
Print a single integer — the number of beautiful bicolorings modulo 998244353 998244353 998244353.
Example
i n p u t \tt input input |
---|
3 4 |
o u t p u t \tt output output |
12 |
i n p u t \tt input input |
---|
4 1 |
o u t p u t \tt output output |
2 |
i n p u t \tt input input |
---|
1 2 |
o u t p u t \tt output output |
2 |
Note
One of possible bicolorings in sample 1 1 1:
Tutorial
本题可以用动态规划来解决,对于这一个
2
×
n
2 \times n
2×n 的矩阵,一定是一列一列进行递推,由于只有
2
2
2 行,所以对于每一列一共只有
4
4
4 种状态,可以令
d
p
i
,
j
,
k
dp_{i, j, k}
dpi,j,k 表示前
i
i
i 列形成
j
j
j 个连通块,第
i
i
i 列的状态为
k
k
k,其中
k
k
k 的状态表示为
k
=
{
0
,
两个白块
1
,
上白下黑
2
,
上黑下白
3
,
两个黑块
k= \left\{\begin{matrix} 0,两个白块 \\ 1,上白下黑 \\ 2,上黑下白 \\ 3,两个黑块 \\ \end{matrix}\right.
k=⎩
⎨
⎧0,两个白块1,上白下黑2,上黑下白3,两个黑块
-
如果前一列是纯色的:新的一列如果和原一列完全一致,则不增加连通块数量;否则,连通块数量总是增加 1 1 1 。
-
如果前一列是混色的:新的一列如果和前一列完全不一致,则增加 2 2 2 个连通块;否则,连通块数量不改变。
了解状态转移方程后即可从前往后遍历得出。
此解法时间复杂度为 O ( n k ) \mathcal O(nk) O(nk)
Solution
import sys
input = lambda: sys.stdin.readline().strip()
mod = 998244353
n, k = map(int, input().split())
"""
dp[i][j][k] 表示前 i 列形成 j 个连通块,方案为 k
k = 0,两个白块
k = 1,上白下黑
k = 2,上黑下白
k = 3,两个黑块
"""
dp = [[[0 for _ in range(4)] for _ in range(2 * n + 1)] for _ in range(n + 1)]
dp[1][1][0] = dp[1][2][1] = dp[1][2][2] = dp[1][1][3] = 1
for i in range(2, n + 1):
for j in range(i * 2 + 1):
dp[i][j][0] = (dp[i - 1][j][0] + dp[i - 1][j][1] + dp[i - 1][j][2] + dp[i - 1][max(j - 1, 0)][3]) % mod
dp[i][j][1] = (dp[i - 1][max(j - 1, 0)][0] + dp[i - 1][j][1] + dp[i - 1][max(j - 2, 0)][2] + dp[i - 1][max(j - 1, 0)][3]) % mod
dp[i][j][2] = (dp[i - 1][max(j - 1, 0)][0] + dp[i - 1][max(j - 2, 0)][1] + dp[i - 1][j][2] + dp[i - 1][max(j - 1, 0)][3]) % mod
dp[i][j][3] = (dp[i - 1][max(j - 1, 0)][0] + dp[i - 1][j][1] + dp[i - 1][j][2] + dp[i - 1][j][3]) % mod
print(sum(dp[n][k][i] for i in range(4)) % mod)