长寿花:dp
当然可以打组合数+CRT什么的,但是其实不必那么麻烦。
先讲那个思路,再转化过来吧。
首先可以发现的一个问题:所有颜色之间是没有区别的,所以我们其实并不在意到底是哪几种,我们只需要知道有几种就可以了。
逐层递推:设dp[i][j]表示到了第i层,这层用了某j种颜色的总方案数。
注意这里为了方便去重,所以dp的含义里是已经确定了j种颜色,所以不要乘上 $ C_m^j $
那么再设s[i]是填到第i曾为止的总方案数那么s[i]=Σdp[i][j]*C[m][j]
还需要预处理一下g数组,g[i][j]表示用恰好i种颜色填满j个格子的方案数。而这j中颜色也是未钦定的所以不带组合数。
那么dp的转移式也就有了,dp[i][j]=(s[i-1]-dp[i-1][j])*g[j][a[i]];
只从上一层转移而来所以可以滚动。
f的预处理也很简单,转移就是从长度短1的状态中选择一种颜色填上。
g[i][j]=g[i-1][j]*(j-1)+g[i-1][j-1]*j;即如果不新增颜色的话那么你能从已有的j种里除上一位刚填的那一种外其他的颜色里选一种,即j-1。
如果你新开了一种颜色,那么就要决定这新开的一种颜色是现有的j种里的哪一种,即乘j。
所以整体思路还是比较简单的。并没有调出我的CRT所以不粘这个代码。
然后想一想简化:当模数不是质数时除法会出问题而加减乘都没事。然而整个代码里只有组合数那一步需要除法。
那么怎么搞掉组合数呢?
需要一些脑洞,我们新开一个数组f。f表示的和g数组差不多,但是是已经钦定了具体是哪j种颜色。
所以g的转移就是f[i][j]=f[i-1][j-1]*(m+1-j)+f[i-1][j]*(j-1);
如果不新增颜色的话那么和f是一样的转移,但是如果是新增了颜色,因为颜色需要确定,所以我们需要明确知道新加入的是哪种颜色。
那就是在还没有被选过的颜色里选一个,一共m种已经用了j-1种,那么剩余的选择就是m-j+1。
那么dp的含义也随之变化,dp亦表示已钦定后的值,那么就相当与乘上那个组合数了。
再考虑dp转移。dp[i][j]=s[i-1]*f[j][a[i]]-dp[i-1][j]*g[j][a[i]];含义的话也类似。
在总方案里我们是已钦定的所以本层到底是哪几种不重要,所以乘f。
而在dp[i-1][j]里我们对于每一种方案里都已确定好颜色,每一个方案对应的本层都有特定的限制,所以需要钦定,用g乘。
代码短多了。时间也快了。
还有其实数组不用滚,用完直接覆盖就行。
#include<cstdio>
long long n,p,m,a[],f[][],dp[],g[][],ld;
main(){
scanf("%lld%lld%lld",&n,&m,&p);for(int i=;i<=n;++i)scanf("%lld",&a[i]);
f[][]=ld=g[][]=;
for(int i=;i<=;++i) for(int j=i;j<=;++j)
f[i][j]=(f[i][j-]*(i-)+f[i-][j-]*(m+-i))%p,g[i][j]=(g[i][j-]*(i-)+g[i-][j-]*i)%p;
for(int i=;i<=n;++i,ld=dp[],dp[]=) for(int j=;j<=a[i]&&j<=m;++j)
(dp[]+=(dp[j]=(ld*f[j][a[i]]-(j<=a[i-])*dp[j]*g[j][a[i]])%p))%=p;
printf("%lld\n",(ld+p)%p);
}
516B
最新文章
- Android 基于Android的手机邮件收发(JavaMail)之三(邮件接收)
- wget 怎么下载https的连接错误: Unable to establish SSL connection
- 困难的串(dfs)
- Unity3D模型的细致纹理问题解决办法
- 4.在二元树中找出和为某一值的所有路径[FindPathsInBinaryTree]
- UI1_UITableViewSearchController
- PERCONA-TOOLKIT 工具的安装与使用2
- MySql函数应用
- linux重新编译内核
- 快速构建Windows 8风格应用28-临时应用数据
- git的入门使用操作
- MongoDB Native Node.js Driver
- Android中弹出dialog后无法捕捉back键
- CentOS TinyProxy http(s)上网代理及置代理上网的方法
- CrawlSpiders模块的使用
- 微信小程序 TOP100 榜单
- 安装了 R2 Integration Servic 之后,SQL Server 2008 Management Studio报错
- 深入C#的String类
- 大数据处理框架之Strom: Storm----helloword
- Sqlserver中分页,2012后支持offset + fetch,2012之前用rownum嵌套查询
热门文章
- 【原】git如何撤销已提交的commit(未push)
- C#刷遍Leetcode面试题系列连载(2): No.38 - 报数
- 三天讲透SpringBoot-初识基础使用
- Spring Boot 2.X(三):使用 Spring MVC + MyBatis + Thymeleaf 开发 web 应用
- Python 爬虫从入门到进阶之路(十)
- 第3章(3) do{}while(0)语句
- 二、docker 镜像容器常用操作(让我们用docker 溜得飞起)
- 详解立即执行函数(function(){}()),(function(){})()
- sql事务的使用及其技巧整理
- Go 零基础 30 min 入门