codeforces 1051 D. Bicolorings (DP)

D. Bicolorings
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a grid, consisting of 22 rows and nn 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 AA and BB belong to the same component if they are neighbours, or if there is a neighbour of AA that belongs to the same component with BB.

Let's call some bicoloring beautiful if it has exactly kk components.

Count the number of beautiful bicolorings. The number can be big enough, so print the answer modulo 998244353998244353.

Input

The only line contains two integers nn and kk (1n10001n1000, 1k2n1k2n) — the number of columns in a grid and the number of components required.

Output

Print a single integer — the number of beautiful bicolorings modulo 998244353998244353.

Examples
Input
3 4
Output
12
Input
4 1
Output
2
Input
1 2
Output
2
Note

One of possible bicolorings in sample 11:

题意
给一个2行n列的矩阵填上黑色和白色,求连通块个数为k个的填色方案数量(mod 998244353)
分析
因为只有两行,为n-1列的矩阵增加1列的情况数只有很少,容易想到用 (i,k)(i,k) 表示 ii 列有 kk 个连通块的矩阵, 但是它在向 i+1i+1 列的矩阵转移时,需要知道最后一列的状态,所以可以用 00, 11, 22, 33表示最后一列为 0000, 0101, 1010, 1111,那么状态就增加一维变成 (i,k,s)(i,k,s),然后就是分析递推关系:

(i,k,0)(i,k,0) 的矩阵,可以由 i1i1 列的矩阵添加一列 0000 得到,当它的结尾为 0000, 0101, 1010, 1111时,分别会让连通块个数:不变,不变,不变,+1,所以 (i,k,0)(i,k,0)(i1,k,0)(i1,k,0), (i1,k,1)(i1,k,1), (i1,k,2)(i1,k,2), (i1,k1,3)(i1,k1,3)得到: dp[i][k][0,0]=   dp[i1][k][0,0]+dp[i1][k][0,1]+dp[i1][k][1,0]+dp[i1][k1][1,1] (i,k,1)的矩阵同理,为i1列的矩阵添加 01,当结尾为 00, 01, 10, 11时,分别会使连通块的个数:+1,不变,+2,+1,所以(i,k,1)(i1,k1,0),(i1,k,1),(i1,k2,2),(i1,k1,3)得到: dp[i][k][0,1]=   dp[i1][k1][0,0]+dp[i1][k][0,1]+dp[i1][k2][1,0]+dp[i1][k1][1,1] (i,k,2)同理可得: dp[i][k][1,0]=   dp[i1][k1][0,0]+dp[i1][k2][0,1]+dp[i1][k][1,0]+dp[i1][k1][1,1] (i,k,3)同理可得: dp[i][k][1,1]=   dp[i1][k1][0,0]+dp[i1][k][0,1]+dp[i1][k][1,0]+dp[i1][k][1,1] 于是得到了完整的递推公式,只需要从下面的状态开始, dp[1][1][0,0]=1dp[1][2][0,1]=1dp[1][2][1,0]=1dp[1][1][1,1]=1 就能推到出所有的状态,最后对dp[n][k]的所有情况求和就是答案了。

注意当k为1时,是不存在k-2的状态的,需要特判一下避免超出数组范围
总结
动态规划的状态定义很关键,必须抓住状态之间的联系;递推式的推导也需要深入思考
代码

 

复制代码
#include<stdio.h>
typedef long long LL;
#define mod 998244353
int dp[1003][2006][4] = {0};
int main() {
    int n, lm;
    scanf("%d %d", &n, &lm);
    //初始化
    dp[1][1][0] = 1;//00
    dp[1][2][2] = 1;//10
    dp[1][2][1] = 1;//01
    dp[1][1][3] = 1;//11
    LL temp=0;
    for (int i = 2; i <= n; ++i) {
        for (int k = 1; k <= (i << 1); ++k) {
            temp = 0;//使用temp求和来避免溢出
            temp =temp
                + dp[i - 1][k][1]//01
                + dp[i - 1][k][0]//00
                + dp[i - 1][k][2]//10
                + dp[i - 1][k - 1][3];//11
            dp[i][k][0] = temp % mod;
            temp = 0;
            temp = temp 
                + dp[i - 1][k][1]//01
                + dp[i - 1][k-1][0]//00
                + (k>=2?dp[i - 1][k - 2][2]:0)//10
                + dp[i - 1][k-1][3];//11
            dp[i][k][1] = temp%mod;
            temp = 0;
            temp = temp 
                + (k>=2?dp[i - 1][k - 2][1]:0)//01
                + dp[i - 1][k-1][0]//00
                + dp[i - 1][k][2]//10
                + dp[i - 1][k-1][3];//11
            dp[i][k][2] = temp%mod;
            temp = 0;
            temp = temp 
                + dp[i - 1][k][1]//01
                + dp[i - 1][k - 1][0]//00
                + dp[i - 1][k][2]//10
                + dp[i - 1][k][3];//11
            dp[i][k][3] = temp%mod;
            temp = 0;
        }
    }
    LL ans = 0;
    ans = ans + dp[n][lm][0] + dp[n][lm][1] + dp[n][lm][2] + dp[n][lm][3];
    ans = ans%mod;
    printf("%I64d\n", ans);
}
复制代码

 

posted @   会打表的toby  阅读(907)  评论(6编辑  收藏  举报
编辑推荐:
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
阅读排行:
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
· 重磅发布!DeepSeek 微调秘籍揭秘,一键解锁升级版全家桶,AI 玩家必备神器!
点击右上角即可分享
微信分享提示