Educational Codeforces Round 51 (Rated for Div. 2)  D. Bicolorings  (dp)_c++

  • 题意:一个\(2\)x\(n\)的矩阵,每个格子可以涂成黑色或者白色,现在问你全部涂完后,连通块个数为\(k\)个一共有多少方案数

  • 题解:每一列总共有\(4\)种情况,白白,黑白,白黑,黑黑,设\(dp[i][j][k]\)表示第\(i\)列,涂第\(j\)种情况,涂完后连通块个数\(k\)的情况数,那么很容易从前一列的状态转移过来,判断前一列的涂色情况和当前这一列构成的连通块数,直接转移即可。

  • 代码

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 998244353;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
    
    int n,k;
    ll dp[1001][2001][4];
    
    int main() {
        scanf("%d %d",&n,&k);
        dp[1][1][0]=1,dp[1][2][1]=1,dp[1][2][2]=1,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])%mod;
                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])%mod;
                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])%mod;
                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])%mod;
            }
        }
        ll ans=(dp[n][k][0]+dp[n][k][1]+dp[n][k][2]+dp[n][k][3])%mod;
        printf("%lld\n",ans);
        return 0;
    }
    
???????????????????????????????????????????? ???????????????????????????????? ???????????? ???????????????? ???????????????? ???????????????????????????????? ???????? ????????????????