长寿花: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
长寿花:dp的更多相关文章
- [CSP-S模拟测试]:长寿花(DP+组合数)
题目描述 庭院里有一棵古树.圣诞节到了,我想给古树做点装饰,给他一个惊喜.他会不会喜欢呢?这棵树可以分为$n$层,第$i$层有$a_i$个防治装饰品的位置,有$m$种颜色的装饰品可供选择.为了能让他喜 ...
- CDOJ 1132 酱神赏花 dp+单调栈降低复杂度+滚动数组
酱神赏花 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 262143/262143KB (Java/Others) Submit St ...
- [NOIP模拟测试34]反思+题解
不要陷入思维定势,如果长时间没有突破就要考虑更改大方向. 不要把简单问题复杂化. 做完的题就先放下,不管能拿多少分.不能过一段时间就回来调一下. $Solutions:$ A.次芝麻 因为$n+m$始 ...
- day01 三级菜单
知识点: 字典, for 循环,if ...else 嵌套 永辉超市 = { '食品饮料':{ '休闲食品':{ '坚果':['山核桃','腰果'], '炒货':['瓜子','花生'] }, '牛奶' ...
- CSPS模拟 52
我貌似曾经说过我是个只会做水题的巨型辣鸡.. 这次证明我水题都不会做.. T1 平均数 区间数$n^2$ 枚举是不可能了 可是好像没有无用的计算量.. 刚想到这里,此时开考15min 看见天皇比手势说 ...
- NOIP模拟 34
次芝麻,喝喝喝,长寿花! 什么鬼畜题面...一看就不是什么正经出题人 skyh双双双AK了..太巨了... T1 次芝麻 稍稍手玩就能发现分界点以一个优美的方式跳动 然后就愉快地帮次货们次掉了这个题- ...
- DP 要求将承载量花光的01背包问题
前言:很久没有发博客了,以后会捡起来,之后很长一段时间内我都会把精力放在攻克DP问题上,所以会经常上传一些DP学习笔记,把一些比较好的,没见过类型的DP问题都会传上来,希望能够变强吧. 因为今天很清醒 ...
- NYOJ 1023 还是回文(DP,花最少费用形成回文串)
/* 题意:给出一串字符(全部是小写字母),添加或删除一个字符,都会产生一定的花费. 那么,将字符串变成回文串的最小花费是多少呢? 思路:如果一个字符串增加一个字符 x可以形成一个回文串,那么从这个字 ...
- [CSP-S模拟测试]:花(DP)
题目传送门(内部题111) 输入格式 一个整数$T$,表示测试数据组数. 每组测试数据占一行,两个整数,分别表示$L$和$S$. 输出格式 对每组数据,输出一个整数表示答案. 样例 样例输入1: 13 ...
随机推荐
- CSS实现带箭头的提示框
我们在很多UI框架中看到带箭头的提示框,感觉挺漂亮,但是之前一直不知道其原理,今天网上找了些资料算是弄清楚原理了: 先上效果图: 原理分析: 上面的箭头有没有觉得很像一个三角形,是的,它就是三角形:只 ...
- B-线性代数-矩阵转置
[TOC] 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblogs.com/nickchen121/ ...
- python基本数据类型及常用功能
1.数字类型 int -int(将字符串转换为数字) a = " print(type(a),a) b = int(a) print(type(b),b) num = " v = ...
- python编程基础之十八
字符串的查找和替换常用函数: str.count(sub,start = 0,end = len(str)) 计算sub 在str中出现的次数,[start,end)寻找区间 str.find(str ...
- Java 语言的发展史
维基百科引入 早期的Java 语言最开始只是Sun计算机(Sun MicroSystems)公司在1990年12月开始研究的一个内部项目.Sun计算机公司的一个叫做帕特里克·诺顿的工程师被公司自己开发 ...
- 小白学 Python(2):基础数据类型(上)
人生苦短,我选Python 引言 前文传送门 小白学 Python(1):开篇 接触一门新的语言,肯定要先了解它的基础数据类型.啥?你问我为啥要先了解基础数据类型? 为了你的生命安全,还是乖乖听我 B ...
- 从.NET CORE2.2升级到3.0过程及遇到的一些问题
RoadFlow工作流引擎从.NET Core2.2升级到3.0遇到了一些问题及解决方式这里记录一下. 1.DLL项目框架从2.2选择到3.0,这个没什么好说的,没有问题.重点的WEB层的一些变化. ...
- Java编程思想——第17章 容器深入研究 读书笔记(一)
这一章将学习散列机制是如何工作的,以及在使用散列容器时怎么样编写hashCode()和equals()方法. 一.容器分类 先上两张图 来概况完整的容器分类 再细说都为什么会有那些特性. 二.填充容器 ...
- php分页的条件
我们在项目开发的过程中避免不了使用分页功能,拿php来说,现在市面上有很多大大小小的php框架,当然了分页这种小功能这些框架中都是拿来直接可以用的. 这些框架的分页功能使用都很方便,配置一下分页所需参 ...
- POI读入Excel用String读取数值类型失真问题(精度丢失)
问题:POI读取Excel数值单元格时,读取的小数数值与真实值不一致 话不多说,直接上代码! public static String getRealStringValue(Cell cell) { ...