CodeForces - 1051D (线性DP)

Posted lis-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 1051D (线性DP)相关的知识,希望对你有一定的参考价值。

题目:https://codeforces.com/problemset/problem/1051/D

题意:一个2行n列的矩形,上面有黑白块,然后问你怎么布置才能有k个连通块,问有多少种方案数

思路:其实就是一个矩阵,我们一次放一列

四种状态    

黑    |   白 | 白 | 黑

白  |  黑 | 白 | 黑

我们dp[n][m][k],第n列第m种状态k个连通块的方案数,现在我们算放每个状态时,计算一次增加了多少个连通块

因为数组太大了,所以我们用滚动数组

然后递推就行了

#include<bits/stdc++.h>
#define maxn 2005
#define mod 998244353 
using namespace std;
typedef long long ll;
ll dp[2][4][maxn];
ll n,k;
int main()
    cin>>n>>k;
    dp[0][0][2]=1;// 0 1
    dp[0][1][2]=1;// 1 0
    dp[0][2][1]=1;// 1 1
    dp[0][3][1]=1;// 0 0
    for(int i=2;i<=n;i++)
        for(int j=0;j<=k;j++)
            dp[1][0][j]=dp[0][0][j];
            dp[1][1][j]=dp[0][1][j];
            dp[1][2][j]=((dp[0][0][j]+dp[0][1][j])%mod+dp[0][2][j])%mod;
            dp[1][3][j]=((dp[0][0][j]+dp[0][1][j])%mod+dp[0][3][j])%mod;
            if(j-2>=0)
                dp[1][0][j]=(dp[1][0][j]+dp[0][1][j-2])%mod;
                dp[1][1][j]=(dp[1][1][j]+dp[0][0][j-2])%mod;
            
            if(j-1>=0)
                dp[1][2][j]=(dp[1][2][j]+dp[0][3][j-1])%mod;
                dp[1][3][j]=(dp[1][3][j]+dp[0][2][j-1])%mod;
                dp[1][0][j]=((dp[1][0][j]+dp[0][2][j-1])%mod+dp[0][3][j-1])%mod;
                dp[1][1][j]=((dp[1][1][j]+dp[0][2][j-1])%mod+dp[0][3][j-1])%mod;
            
        
        for(int j=0;j<=k;j++)
            for(int z=0;z<=3;z++)
                dp[0][z][j]=dp[1][z][j];
                dp[1][z][j]=0;
            
        
     
    ll sum=((dp[0][0][k]+dp[0][1][k])%mod+(dp[0][2][k]+dp[0][3][k])%mod)%mod;
    printf("%lld",sum);
 

 

以上是关于CodeForces - 1051D (线性DP)的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces 1051d:连通块 DP

CF1051D Bicolorings

codeforces736D. Permutations(线性代数)

Educational Codeforces Round 37F. SUM and REPLACE 线段树+线性筛

CF1051D Bicolorings 递推

codeforces CF920F SUM and REPLACE 线段树 线性筛约数