Codeforces传送门
洛谷传送门
题目描述
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 .
输入输出格式
输入格式:
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.
输出格式:
Print a single integer — the number of beautiful bicolorings modulo $998244353 $.
输入输出样例
输入样例#1:
3 4
输出样例#1:
12
输入样例#2:
4 1
输出样例#2:
2
输入样例#3:
1 2
输出样例#3:
2
说明
One of possible bicolorings in sample 1 1 1 :
解题分析
一开始想的是轮廓线 d p dp dp, 然后发现状态有点多, 然后发现好像暴力两行一起转移就可以了。
显然如果上一行的状态共有4种情况:黑黑,黑白,白白,白黑
, 那么转移就是
O
(
4
∗
4
)
O(4*4)
O(4∗4)的, 总复杂度
O
(
16
∗
N
)
O(16*N)
O(16∗N)。
代码如下:
#include <cstdio>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 1050
#define MOD 998244353ll
#define ll long long
int dp[2][2][MX][MX * 2];
int n, k;
IN void mod(int &x, R int y) {x += y; if(x >= MOD) x -= MOD;}
int main(void)
{
scanf("%d%d", &n, &k);
dp[0][0][1][1] = 1;
dp[1][1][1][1] = 1;
dp[0][1][1][2] = 1;
dp[1][0][1][2] = 1;
for (R int i = 2; i <= n; ++i)
{
int bd = i * 2, pre = i - 1;
for (R int j = 1; j <= bd; ++j)
{
mod(dp[0][0][i][j + 1], dp[1][1][pre][j]);
mod(dp[0][0][i][j], dp[0][1][pre][j]);
mod(dp[0][0][i][j], dp[1][0][pre][j]);
mod(dp[0][0][i][j], dp[0][0][pre][j]);
mod(dp[1][1][i][j + 1], dp[0][0][pre][j]);
mod(dp[1][1][i][j], dp[0][1][pre][j]);
mod(dp[1][1][i][j], dp[1][0][pre][j]);
mod(dp[1][1][i][j], dp[1][1][pre][j]);
mod(dp[0][1][i][j + 2], dp[1][0][pre][j]);
mod(dp[0][1][i][j + 1], dp[1][1][pre][j]);
mod(dp[0][1][i][j + 1], dp[0][0][pre][j]);
mod(dp[0][1][i][j], dp[0][1][pre][j]);
mod(dp[1][0][i][j + 2], dp[0][1][pre][j]);
mod(dp[1][0][i][j + 1], dp[1][1][pre][j]);
mod(dp[1][0][i][j + 1], dp[0][0][pre][j]);
mod(dp[1][0][i][j], dp[1][0][pre][j]);
}
}
int ans = 0;
mod(ans, dp[1][1][n][k]), mod(ans, dp[0][0][n][k]), mod(ans, dp[0][1][n][k]), mod(ans, dp[1][0][n][k]);
printf("%d", ans);
}