1. 程式人生 > >Educational Codeforces Round 51 (Rated for Div. 2), problem: (D) Bicolorings(DP)

Educational Codeforces Round 51 (Rated for Div. 2), problem: (D) Bicolorings(DP)

每加一列的組合個數可以遞推得到,顯然具有最優子結構,可用DP的方法。每加一列有四種可能的情況,所以狀態轉移方程為:
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])%998244353
dp[i][j][1]=(dp[i-1][j-1][0]+dp[i-1][j][1]+dp[i-1][j-2][2]+dp[i-1][j-1][3])%998244353
dp[i][j][2]=(dp[i-1][j-1][0]+dp[i-1][j-2][1]+dp[i-1][j][2]+dp[i-1][j-1][3])%998244353
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])%998244353

ac程式碼:

#include <bits/stdc++.h>
#define FOR(I,A,B) for(int I = (A); I < (B); I++)
#define FORE(I,A,B) for(int I = (A); I <= (B); I++)
#define PRII pair<int,int> 
#define LL long long 
#define INF 1000000001

using namespace std;
int n,k;
LL dp[1005][2005][4];	 
int main()
{
	cin>>n>>
k; dp[1][2][1]=1;dp[1][2][2]=1; FORE(i,1,n){ dp[i][1][0]=1;dp[i][1][3]=1;} FORE(i,2,n){ FORE(j,2,min(k,2*i)){ 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])%998244353; dp[i][j][1]=(dp[i-1][j-1][0]+dp[i-1][j][1]+dp[i-1][j-2][2]+dp[i-1][j-1][3])%998244353; dp[i][j][2
]=(dp[i-1][j-1][0]+dp[i-1][j-2][1]+dp[i-1][j][2]+dp[i-1][j-1][3])%998244353; 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])%998244353; } } printf("%d\n",(dp[n][k][0]+dp[n][k][1]+dp[n][k][2]+dp[n][k][3])%998244353); return 0; }