Educational Codeforces Round 51 (Rated for Div. 2) D
阿新 • • 發佈:2018-12-12
題意:對格子著色,僅能著黑色或白色,問色塊數為的著色方案有多少種。色塊定義如下,若兩個格子顏色相同且相鄰,則屬於同一色塊;若兩個格子顏色相同且所屬色塊相鄰,則屬於同一色塊;否則屬於不同色塊。
思路:這題的矩陣很有特點,是,那麼就可以很容易的想到是利用狀態壓縮來進行轉移.我們設表示前列,第列的狀態是,色塊數為的方案數 那麼對於每一個都可以由四種狀態得來.所以只需要列舉列數和色塊數,然後每次轉移16次就行了. 具體轉移參考程式碼
#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 998244353;
ll dp[1005][10][2005];//表示前i列,第i列的狀態是j,色塊數為k的方案數
int n, k;
int main() {
scanf("%d%d", &n, &k);
dp[1][0][1] = 1;
dp[1][1][2] = 1;
dp[1][2][2] = 1;
dp[1][3][1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= k; j++) {
dp[i][0][j] += dp[i - 1][0][j];
dp[i][0][j] += dp[i - 1][1][j];
dp[i][0][j] += dp[i - 1][2][j];
dp[i][0][j] += dp[i - 1][3][j - 1];
dp[i][1][j] += dp[i - 1][0][j - 1];
dp[i][1][j] += dp[i - 1][1][j];
if(j!=1)dp[i][1][j] += dp[i - 1][2][j - 2];
dp[i][1][j] += dp[i - 1][3][j - 1];
dp[i][2][j] += dp[i - 1][0][j - 1];
if(j!=1)dp[i][2][j] += dp[i - 1][1][j - 2];
dp[i][2][j] += dp[i - 1][2][j];
dp[i][2][j] += dp[i - 1][3][j - 1];
dp[i][3][j] += dp[i - 1][0][j - 1];
dp[i][3][j] += dp[i - 1][1][j];
dp[i][3][j] += dp[i - 1][2][j];
dp[i][3][j] += dp[i - 1][3][j];
for (int k = 0; k < 4; k++) dp[i][k][j] %= mod;
}
}
ll ans = 0;
for (int i = 0; i < 4; i++) ans += dp[n][i][k];
ans %= mod;
printf("%lld\n", ans);
return 0;
}