codeforces 1051 D. Bicolorings (DP)
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.
The only line contains two integers nn and kk (1≤n≤10001≤n≤1000, 1≤k≤2n1≤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 998244353998244353.
3 4
12
4 1
2
1 2
2
One of possible bicolorings in sample 11:
![](http://codeforces.com/predownloaded/f7/4d/f74d06fb2f4473497e705ffd0ab6921fa8437844.png)
(i,k,0)(i,k,0) 的矩阵,可以由 i−1i−1 列的矩阵添加一列 0000 得到,当它的结尾为 0000, 0101, 1010, 1111时,分别会让连通块个数:不变,不变,不变,+1,所以 (i,k,0)(i,k,0)由 (i−1,k,0)(i−1,k,0), (i−1,k,1)(i−1,k,1), (i−1,k,2)(i−1,k,2), (i−1,k−1,3)(i−1,k−1,3)得到: dp[i][k][0,0]= dp[i−1][k][0,0]+dp[i−1][k][0,1]+dp[i−1][k][1,0]+dp[i−1][k−1][1,1] (i,k,1)的矩阵同理,为i−1列的矩阵添加 01,当结尾为 00, 01, 10, 11时,分别会使连通块的个数:+1,不变,+2,+1,所以(i,k,1)由(i−1,k−1,0),(i−1,k,1),(i−1,k−2,2),(i−1,k−1,3)得到: dp[i][k][0,1]= dp[i−1][k−1][0,0]+dp[i−1][k][0,1]+dp[i−1][k−2][1,0]+dp[i−1][k−1][1,1] (i,k,2)同理可得: dp[i][k][1,0]= dp[i−1][k−1][0,0]+dp[i−1][k−2][0,1]+dp[i−1][k][1,0]+dp[i−1][k−1][1,1] (i,k,3)同理可得: dp[i][k][1,1]= dp[i−1][k−1][0,0]+dp[i−1][k][0,1]+dp[i−1][k][1,0]+dp[i−1][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); }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
· 重磅发布!DeepSeek 微调秘籍揭秘,一键解锁升级版全家桶,AI 玩家必备神器!