codeforces 1027E - Inverse Coloring(dp)

题目网址http://codeforces.com/problemset/problem/1027/E

题意:

       n*n的格子,被染成白色或者黑色,每一行与其相邻的那一行的颜色要么完全相同,要么完全不同,其列也是如此。在一个n*n的矩阵中,满足条件,其中格子颜色全部相同子矩形的格子数不超过k。

思路:

   因为题目要求的特性,我们发现只要确定一行一列的话,就可以确定整个n*n的矩阵的染色情况。

  我们定义 dp[i][j] 长度为 i 的行,最多有连续长度为 j 的格子数颜色相同的染色方案的数目 。

 那么递推方程很容易得出。

这样我们可以用差分的思想,得出长度为n 的连续长度为j的染色方案数目,为dp[n] [j]  - dp[n][j-1] ;

那么我们通过枚举行列连续染色数目的情况,就可以得到最终答案。 只要行的连续长度a 和列的连续长度 b  a*b

注意最后得到的答案还要*2 ,因为把黑白两色互换的话,是可以同样的结果。

 代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define  ll long long
using namespace std;
const int maxn = 500+50;
const ll mod = 998244353;
ll dp[maxn][maxn];
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    dp[0][0] = 1;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=i; j++)
            for(int k=1; k<=j; k++)
            {
                dp[i][j] = (dp[i][j] + dp[i-k][min(j,i-k)])%mod; //因为dp[i][j] 的j<=i,所以需要取min
            }
    for(int i=n; i>=1; i--)
        dp[n][i] = (dp[n][i] - dp[n][i-1] + mod )%mod;
    ll ans = 0;
    for(int i=1; i<=n; i++)
        for(int j=1; j*i

 

你可能感兴趣的:(codeforces,动态规划)