D. Bicolorings(计数DP)

d p 其实还是比较经典的格子dp

d p [ i ] [ j ] [ q ] i j , i q 设dp[i][j][q]为放完第i列有j个连通块,第i列状态是q的答案数

q [ 0 , 1 , 2 , 3 ] , i q取[0,1,2,3],分别表示第i列放黑白,白黑,黑黑,白白

, , 因为转移比较简单,直接看代码也能看懂,这里不写

, 代码中用了滚动数组,因为当前列只和上一列有关

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
int n,k,ans;
int dp[2][2001][4];//分别表示第几列,几个连通块,哪种状态
//0,1,2,3表示黑白,白黑,黑黑,白白 
signed main()
{
	cin >> n >> k;
	dp[1][2][0]=dp[1][2][1]=1;
	dp[1][1][2]=dp[1][1][3]=1;
	
	for(int i=2;i<=n;i++)
	{
		int u=i%2,v=(i%2)^1;
		for(int j=1;j<=k;j++)
		{
			int s=max(j-2,(int)0);
			dp[u][j][0]=dp[v][j][0]+dp[v][s][1]+dp[v][j-1][2]+dp[v][j-1][3];
			dp[u][j][1]=dp[v][j][1]+dp[v][s][0]+dp[v][j-1][2]+dp[v][j-1][3];
			dp[u][j][2]=dp[v][j][2]+dp[v][j-1][3]+dp[v][j][0]+dp[v][j][1];
			dp[u][j][3]=dp[v][j][3]+dp[v][j-1][2]+dp[v][j][0]+dp[v][j][1];
			for(int q=0;q<=3;q++)
				dp[u][j][q]%=mod;
		}
	}
	for(int i=0;i<=3;i++)
		ans = (ans + dp[n%2][k][i] )%mod;
	cout << ans;
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/106851865