Codeforces #511 div2 D. Bicolorings(dp)

传送门

类似状压dp的思路吧,只有两行,所以每一列只有4个状态,所以可以考虑枚举每一列,这样复杂度是On*4,n只有1000,题目又要求把方格分成k个连通块,我们在dp中再加一维即可,k最大是2*n的,所以最多做8e6次循环。

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long dp[5][1100][2100];
int main()
{
    int n,k;
    cin>>n>>k;
    memset(dp,0,sizeof(dp));
    dp[0][1][1]=1;
    dp[1][1][1]=0;
    dp[2][1][1]=0;
    dp[3][1][1]=1;

    dp[0][1][2]=0;
    dp[1][1][2]=1;
    dp[2][1][2]=1;
    dp[3][1][2]=0;


    for(int j=2; j<=n; j++)
        for(int i=0; i<=3; i++)
            for(int t=1; t<=k; t++)
            {
                if(i==0)
                    dp[i][j][t]=(dp[0][j-1][t]+dp[1][j-1][t]+dp[2][j-1][t]+dp[3][j-1][t-1])%mod;
                else if(i==1)
                    dp[i][j][t]=(dp[0][j-1][t-1]+dp[1][j-1][t]+dp[2][j-1][t-2]+dp[3][j-1][t-1])%mod;
                else if(i==2)
                    dp[i][j][t]=(dp[0][j-1][t-1]+dp[1][j-1][t-2]+dp[2][j-1][t]+dp[3][j-1][t-1])%mod;
                else
                    dp[i][j][t]=(dp[0][j-1][t-1]+dp[1][j-1][t]+dp[2][j-1][t]+dp[3][j-1][t])%mod;

            }

    cout<<(dp[0][n][k]+dp[1][n][k]+dp[2][n][k]+dp[3][n][k])%mod<<endl;
}

猜你喜欢

转载自blog.csdn.net/zero___zero/article/details/82800293