【組合數學dp】Educational Codeforces Round 51 (Rated for Div. 2) D. Bicolorings
阿新 • • 發佈:2018-12-24
Step1 Problem:
給你 2*n 的矩陣,你可以對於每個格子填塗黒色或者白色,如果相鄰顏色一樣看成同一塊,問你塗完後恰好有 k 塊的方案數。
資料範圍:
1 <= n <= 1000, 1 <= k <= 2n.
Step2 Ideas:
總有一股組合數學的味道。
直接說題解:
dp[i][0][k]: 恰好為 k 塊上下都黑的方案數
dp[i][1][k]: 恰好為 k 塊上黑下白的方案數
dp[i][2][k]: 恰好為 k 塊上白下黑的方案數
dp[i][3][k]: 恰好為 k 塊上下都白的方案數
Step3 Code:
#include<bits/stdc++.h> using namespace std; #define ll long long const int N = 1e3+5; const int MOD = 998244353; ll dp[N][4][2*N]; int main() { int n, K; scanf("%d %d", &n, &K); K = K+2;//這樣就陣列就不會訪問到負數了 dp[1][0][1+2] = 1; dp[1][1][2+2] = 1; dp[1][2][2+2] = 1; dp[1][3][1+2] = 1; ll ans = 0; for(int i = 2; i <= n; i++) { for(int k = 3; k <= K; k++) { dp[i][0][k] = dp[i-1][0][k] + dp[i-1][1][k] + dp[i-1][2][k] + dp[i-1][3][k-1], dp[i][0][k] %= MOD; dp[i][1][k] = dp[i-1][0][k-1] + dp[i-1][1][k] + dp[i-1][2][k-2] + dp[i-1][3][k-1], dp[i][1][k] %= MOD; dp[i][2][k] = dp[i-1][0][k-1] + dp[i-1][1][k-2] + dp[i-1][2][k] + dp[i-1][3][k-1], dp[i][2][k] %= MOD; dp[i][3][k] = dp[i-1][0][k-1] + dp[i-1][1][k] + dp[i-1][2][k] + dp[i-1][3][k], dp[i][3][k] %= MOD; } } for(int i = 0; i < 4; i++) ans += dp[n][i][K]; ans %= MOD; printf("%lld\n", ans); return 0; }