博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF140E New Year Garland
阅读量:4599 次
发布时间:2019-06-09

本文共 1636 字,大约阅读时间需要 5 分钟。

题解:

容斥(?)+$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
#include
#include
using namespace std;typedef long long ll;const int L = 5050;const int N = 1000050;template
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\n",ans); return 0;}

 

转载于:https://www.cnblogs.com/LiGuanlin1124/p/10356613.html

你可能感兴趣的文章
Java_包装类
查看>>
ubuntu14.04安装与配置nginx服务器
查看>>
利用/dev/urandom文件创建随机数
查看>>
js遍历获取表格内数据方法
查看>>
DVWA渗透测试环境搭建
查看>>
bzoj2219: 数论之神
查看>>
bzoj 3261: 最大异或和
查看>>
「折腾」用word发布博客
查看>>
C# 基本函数
查看>>
iOS审核秘籍】提审资源检查大法
查看>>
辗转相除法
查看>>
A2-02-29.DML-MySQL DELETE
查看>>
vue 路由跳转
查看>>
having 子句
查看>>
常用排序算法
查看>>
一个很好介绍js的例子
查看>>
POJ 3122 Pie
查看>>
RHEL存储扩容
查看>>
关于mongodb的安装运行
查看>>
Ubuntu总结常用命令记录
查看>>