CF140E New Year Garland

Posted liguanlin1124

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF140E New Year Garland相关的知识,希望对你有一定的参考价值。

题目描述

题解:

容斥(?)+$dp$。

定义状态$dp[i][j]$表示前$i$层,其中第$i$层用了$j$种颜色。

这个时候我们发现还缺一个系数,就是用$i$种颜色涂$j$个格子的方案数(颜色无顺序要求)。

定义这个东西叫$f[i][j]$。

然后有:$$dp[i][j]=f[l[i]][j]*(C^{m}_{j}*sum dp[i-1][k]-dp[i-1][j])$$

结果发现这个东西涉及到组合数取模非质数。

当场自闭。

后来看题解,发现这个东西有个巧妙的处理方法。

把$f$的定义改一下,要求涂色时颜色有序,比如$12345$、$12123$合法,而$54321$、$12356$不合法。

于是我们发现$f$是可以递推的。$f[i][j]=f[i-1][j-1]+(j-1)*f[i-1][j]$

然后代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int L = 5050;
const int N = 1000050;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){c=c*10+ch-0;ch=getchar();}
    x = f*c;
}
int n,m,p,l[N],op,mx;
ll A[L],B[L],dp[2][N],f[L][L];
void init()
{
    A[0]=1;
    for(int i=1;i<=mx;i++)A[i]=A[i-1]*(m-i+1)%p;
    B[0]=1;
    for(int i=1;i<=mx;i++)B[i]=B[i-1]*i%p;
    f[0][0]=1;
    for(int i=1;i<=mx;i++)
        for(int j=1;j<=i&&j<=m;j++)
            f[i][j]=(f[i-1][j-1]+((j-1)*f[i-1][j]%p))%p;
}
int main()
{
    read(n),read(m),read(p);
    for(int i=1;i<=n;i++)read(l[i]),mx=mx>l[i]?mx:l[i];
    init();
    for(int i=1;i<=n;i++,op^=1)
    {
        ll k=0;
        if(i==1)k=1;
        else for(int j=1;j<=m&&j<=l[i-1];j++)k=(k+dp[op][j])%p;
        for(int j=1;j<=m&&j<=l[i];j++)
            dp[!op][j]=f[l[i]][j]*((A[j]*k%p-B[j]*dp[op][j]%p+p)%p)%p;
        for(int j=1;j<=m&&j<=l[i-1];j++)
            dp[op][j]=0;
    }
    ll ans = 0;
    for(int i=1;i<=m&&i<=l[n];i++)ans=(ans+dp[op][i])%p;
    printf("%lld
",ans);
    return 0;
}

 

以上是关于CF140E New Year Garland的主要内容,如果未能解决你的问题,请参考以下文章

CF140E New Year Garland (计数问题)

CF104E New Year Garland

A - New Year Garland

codeforces 140E.New Year Garland

「CF1286A」Garland

CF - 1106 E Lunar New Year and Red Envelopes DP