题目链接:Codeforces - Bicolorings
dp[i][j][k]为前i行,联通块个数为j,第i行状态为k的方案数。
然后暴力转移即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e3+10,mod=998244353;
int n,k,dp[N][N<<1][1<<2],res;
signed main(){
cin>>n>>k;
dp[1][1][0]=dp[1][2][1]=dp[1][2][2]=dp[1][1][3]=1;
for(int i=2;i<=n;i++)
for(int j=1;j<=k;j++){
dp[i][j][0]=dp[i-1][j][0]+dp[i-1][j][1]+dp[i-1][j][2]+dp[i-1][j-1][3];
dp[i][j][1]=dp[i-1][j-1][0]+dp[i-1][j][1]+dp[i-1][j-1][3];
if(j>=2) dp[i][j][1]+=dp[i-1][j-2][2];
dp[i][j][2]=dp[i-1][j-1][0]+dp[i-1][j][2]+dp[i-1][j-1][3];
if(j>=3) dp[i][j][2]+=dp[i-1][j-2][1];
dp[i][j][3]=dp[i-1][j-1][0]+dp[i-1][j][1]+dp[i-1][j][2]+dp[i-1][j][3];
for(int s=0;s<4;s++) dp[i][j][s]%=mod;
}
for(int s=0;s<4;s++) res+=dp[n][k][s];
cout<<res%mod;
return 0;
}