http://codeforces.com/contest/1051
随手捞到的以前没有补完的场,
D. Bicolorings
一个dp题,题意是,有一个2*n的矩阵,其中每个色块可黑可白,重要的是里面的连通块数,题目将给出n和k,让你求恰好有k个连通块的情况下的方案数。
从列来考虑,假设已知前一个矩阵的最后一列,和其方案数,(可以用00、01、10、11的二进制数来表示)那么当前dp[i][K][0]表示第i列有K个连通块且末尾列为00的方案数
前一列可能是00、01、10、11其中任何一个,分别加上00时连通块个数的状态为不变、+1、+1、+1,于是有dp[i][K][0] = dp[i-1][K][0] + dp[i-1][K-1][1] + dp[i-1][K-1][2] + dp[i-1][K-1][3];
其他情况类比推理一下就好了,要注意的地方是取模,分分钟爆int所以每次加法都要取一次mod最后出结果的时候也是
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int mod =998244353 ; 5 int n,T,k,dp[1200][2400][5]; 6 ll temp; 7 8 int main(){ 9 10 cin>>n>>k; 11 dp[1][1][0] = dp[1][1][3] = dp[1][2][1] = dp[1][2][2] = 1; 12 13 for(int i = 2;i <= n;++i){ 14 for(int k = 1;k <= (i<<1);++k){ 15 temp = ((dp[i-1][k][0]+dp[i-1][k][1])%mod+dp[i-1][k][2])%mod+dp[i-1][k-1][3]; 16 temp = temp % mod; 17 dp[i][k][0] = temp; 18 //第i列为00时 连通块为k可以由第i-1列的四个状态得到,接下来01,10,11时同理 19 temp =( dp[i-1][k-1][0]+dp[i-1][k][1])%mod+dp[i-1][k-1][3]; 20 temp%=mod; 21 if(k>=2)temp+=dp[i-1][k-2][2],temp%=mod; 22 temp = temp % mod; 23 dp[i][k][1] = temp; 24 // 25 temp = (dp[i-1][k-1][0]+dp[i-1][k][2])%mod+dp[i-1][k-1][3]; 26 temp%=mod; 27 if(k>=2)temp+=dp[i-1][k-2][1],temp%=mod; 28 temp = temp % mod; 29 dp[i][k][2] = temp; 30 // 31 temp = ((dp[i-1][k-1][0]+dp[i-1][k][1])%mod+dp[i-1][k][2])%mod+dp[i-1][k][3]; 32 temp = temp % mod; 33 dp[i][k][3] = temp; 34 } 35 } 36 ll ans = ((dp[n][k][0] + dp[n][k][1]) %mod+ dp[n][k][2] )%mod+ dp[n][k][3];ans%=mod; 37 cout<<ans<<endl; 38 }