1. 程式人生 > >Codeforces 1051 D.Bicolorings(DP)

Codeforces 1051 D.Bicolorings(DP)

[1] function code += 塗色 c++ 轉移 pac ons

Codeforces 1051 D.Bicolorings

題意:一個2×n的方格紙,用黑白給格子塗色,要求分出k個連通塊,求方案數。
思路:用0,1表示黑白,則第i列可以塗00,01,10,11,(可以分別用0,1,2,3表示),於是定義dp[i][j][k]:塗到第i列分為j個連通塊且第i列塗法為k的方案數,則有了代碼中的轉移式,共16種轉移類型。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<string>
#include<vector>
#include<cmath>
#include<climits>
#include<functional>
#include<set>
#define dd(x) cout<<#x<<" = "<<x<<" "
#define de(x) cout<<#x<<" = "<<x<<endl
#define fi first
#define se second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef vector<int> V;
typedef map<int,int> M;
typedef queue<int> Q;
typedef priority_queue<int> BQ;
typedef priority_queue<int,vector<int>,greater<int> > SQ;
const int maxn=1e3+10,INF=0x3f3f3f3f,mod=998244353;
int dp[maxn][maxn<<1][5];//0->00, 1->01, 2->10, 3->11
inline int add(int a,int b)
{
  a+=b;
  if (a>=mod)
    a-=mod;
  return a;
}
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    dp[1][1][0]=dp[1][2][1]=dp[1][2][2]=dp[1][1][3]=1;
    for (int i=2;i<=n;++i)
    {
      for (int j=1;j<=2*i;++j)
      {
        dp[i][j][0]=add(dp[i][j][0],add(dp[i-1][j-1][3],add(dp[i-1][j][2],add(dp[i-1][j][1],dp[i-1][j][0]))));
        dp[i][j][1]=add(dp[i][j][1],add(dp[i-1][j-1][0],add(dp[i-1][j][1],add(j>=2?dp[i-1][j-2][2]:0,dp[i-1][j-1][3]))));
        dp[i][j][2]=add(dp[i][j][2],add(dp[i-1][j-1][0],add(dp[i-1][j][2],add(j>=2?dp[i-1][j-2][1]:0,dp[i-1][j-1][3]))));
        dp[i][j][3]=add(dp[i][j][3],add(dp[i-1][j-1][0],add(dp[i-1][j][1],add(dp[i-1][j][2],dp[i-1][j][3]))));
      }
    }
    printf("%d",add(dp[n][k][0],add(dp[n][k][1],add(dp[n][k][2],dp[n][k][3]))));
    return 0;
}

Codeforces 1051 D.Bicolorings(DP)