CF140E New Year Garland (计数问题)

Posted guapisolo

tags:

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

用$m$种颜色的彩球装点$n$层的圣诞树。圣诞树的第$i$层恰由$a_{i}$个彩球串成一行,且同一层内的相邻彩球颜色不同,同时相邻两层所使用彩球的颜色集合不 同。求有多少种装点方案,答案对$p$取模。

好神的计数问题,zwz Orz

 

先只考虑在一行内的彩球的方案数

定义$g[i][j]$表示一共有$i$个球串成一行,一共用了$j$种颜色的方案数

因为所有颜色都是等价的,我们可以利用最小表示法来简化计数,比如让颜色编号为$x+1$的球第一次出现的位置,在颜色编号为$x$的球之前。实际的方案数是$g[i][j]cdot j!$

这样递推关系就简单多了

加入一个新颜色的球,$g[i][j]+=g[i-1][j-1]$

加入一个旧颜色的球,颜色不能和第$i-1$个球相同,$g[i][j]+=(j-1)g[i-1][j]$

$g[i][j]=g[i-1][j-1]+(j-1)g[i-1][j]$

 

在考虑行行之间的影响

定义$f[i][j]$表示前$i$行,其中第$i$行选了$j$种颜色的方案数

如果没有相邻两行集合不同这种限制

$f[i][j]=C_{m}^{j}cdot g[a_{i}][j]cdot sum f[i-1][k]$

如果加上限制,

$f[i][j]=C_{m}^{j}cdot g[a_{i}][j]cdot j!sum f[i-1][k]-g[a_{i}][j]cdot j!cdot f[i-1][j]$

利用前缀和优化可以$O(1)$转移

$f[i][j]$的状态数也仅仅是$O(sum a_{i})$,用滚动数组记录

 

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define N1 5010
 6 #define M1 1000010
 7 #define dd double
 8 #define ll long long 
 9 using namespace std;
10 
11 int gint()
12 {
13     int ret=0,fh=1;char c=getchar();
14     while(c<0||c>9){if(c==-)fh=-1;c=getchar();}
15     while(c>=0&&c<=9){ret=ret*10+c-0;c=getchar();}
16     return ret*fh;
17 }
18 int n,m,mx,P;
19 
20 int f[2][N1],g[N1][N1],am[N1],mul[N1],a[M1];
21 
22 int main()
23 {
24     int i,j,x;
25     scanf("%d%d%d",&n,&m,&x);
26     for(i=1;i<=n;i++) scanf("%d",&a[i]), mx=max(mx,a[i]);
27     const int p=x;
28     g[0][0]=g[1][1]=1;
29     for(i=2;i<=mx;i++) for(j=1;j<=i;j++) g[i][j]=(1ll*(j-1)*g[i-1][j]%p+g[i-1][j-1])%p;
30     mul[0]=mul[1]=1; am[0]=1;
31     for(i=1;i<=min(m,mx);i++) am[i]=1ll*am[i-1]*(m-i+1)%p;
32     for(i=2;i<=mx;i++) mul[i]=1ll*mul[i-1]*i%p;
33     int now=1,pst=0,snow=0,spst=1;
34     f[pst][0]=1;
35     for(i=1;i<=n;i++)
36     {
37         snow=0; memset(f[now],0,sizeof(f[now]));
38         for(j=1;j<=min(m,a[i]);j++)
39             f[now][j]=(1ll*am[j]*g[a[i]][j]%p*spst%p-1ll*f[pst][j]*mul[j]%p*g[a[i]][j]%p+p)%p, (snow+=f[now][j])%=p;
40         swap(now,pst); swap(snow,spst);
41     }
42     printf("%d
",spst);
43     return 0;
44 }

 

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

CF140E New Year Garland (计数问题)

CF104E New Year Garland

A - New Year Garland

codeforces 140E.New Year Garland

CF 750C New Year and Rating(思维题)

cf723a The New Year: Meeting Friends