题目:https://codeforces.com/problemset/problem/1051/D
题意:一个2行n列的矩形,上面有黑白块,然后问你怎么布置才能有k个连通块,问有多少种方案数
思路:其实就是一个矩阵,我们一次放一列
四种状态
黑 | 白 | 白 | 黑
白 | 黑 | 白 | 黑
我们dp[n][m][k],第n列第m种状态k个连通块的方案数,现在我们算放每个状态时,计算一次增加了多少个连通块
因为数组太大了,所以我们用滚动数组
然后递推就行了
#include<bits/stdc++.h> #define maxn 2005 #define mod 998244353 using namespace std; typedef long long ll; ll dp[2][4][maxn]; ll n,k; int main(){ cin>>n>>k; dp[0][0][2]=1;// 0 1 dp[0][1][2]=1;// 1 0 dp[0][2][1]=1;// 1 1 dp[0][3][1]=1;// 0 0 for(int i=2;i<=n;i++){ for(int j=0;j<=k;j++){ dp[1][0][j]=dp[0][0][j]; dp[1][1][j]=dp[0][1][j]; dp[1][2][j]=((dp[0][0][j]+dp[0][1][j])%mod+dp[0][2][j])%mod; dp[1][3][j]=((dp[0][0][j]+dp[0][1][j])%mod+dp[0][3][j])%mod; if(j-2>=0){ dp[1][0][j]=(dp[1][0][j]+dp[0][1][j-2])%mod; dp[1][1][j]=(dp[1][1][j]+dp[0][0][j-2])%mod; } if(j-1>=0){ dp[1][2][j]=(dp[1][2][j]+dp[0][3][j-1])%mod; dp[1][3][j]=(dp[1][3][j]+dp[0][2][j-1])%mod; dp[1][0][j]=((dp[1][0][j]+dp[0][2][j-1])%mod+dp[0][3][j-1])%mod; dp[1][1][j]=((dp[1][1][j]+dp[0][2][j-1])%mod+dp[0][3][j-1])%mod; } } for(int j=0;j<=k;j++){ for(int z=0;z<=3;z++){ dp[0][z][j]=dp[1][z][j]; dp[1][z][j]=0; } } } ll sum=((dp[0][0][k]+dp[0][1][k])%mod+(dp[0][2][k]+dp[0][3][k])%mod)%mod; printf("%lld",sum); }