Codeforces1027E-Inverse Coloring

Codeforces1027E-Inverse Coloring_第1张图片
题解:
我们可以把这个矩形的的每一行设一个值 ai a i ,每一列设定一个值 bi b i 。其中 ai a i bi b i = = 0 0 1 1
然后对于格子 (ij) ( i , j ) 其颜色就是: ai a i xor x o r bj b j
可以保证这样一定满足前两个条件。
然后就是要满足第 3 3 个条件。
无非就是 a a 中最长的一段连续相同的值和 b b 中最长的一段连续相同的值的乘积不超过 k k
就可以用 dp d p 求出:对于最长连续相同长度刚好为 x x 的,总长度为 n n 01 01 序列的方案数。
发现这个刚好为 x x 其实不便表示,所以可以用一下差分的思想:求出最长长度不超过 x x 的方案数,设为 fx f x ,然后我们要的就是 fx f x fx1 f x − 1 。这样就排除了所有长度未达到 x x 的方案。
然后这个 dp d p 就非常简单了
dp[i][j] d p [ i ] [ j ] 表示前 i i 个位置,最长连续相同不超过 j j 的方案数。
然后 dp[i][j]=min(j,i)k=1dp[ik][j] d p [ i ] [ j ] = ∑ k = 1 m i n ( j , i ) d p [ i − k ] [ j ]
算出 f f 后两两匹配计算答案。
由于黑白不同,最后答案 2 ∗ 2 即可。
Code C o d e :

#include
#include
#define mod 998244353
#define N 505
using namespace std;
int n,k;
long long dp[N][N],f[N],ans;
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        dp[0][i]=1;
        for(int j=1;j<=n;j++)
            for(int k=1;k<=min(i,j);k++)
                dp[j][i]=(dp[j][i]+dp[j-k][i])%mod;
    }
    for(int i=1;i<=n;i++)
        f[i]=(dp[n][i]-dp[n][i-1]+mod)%mod;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i*j*f[j]%mod)%mod;
    printf("%lld\n",ans*2%mod);
    return 0;
}

你可能感兴趣的:(=====dp=====,#,基本dp,Codeforces)