排列相关计数 笔记
本文复制自以往相关笔记,添加了部分内容。
类型一
在此类 DP 中,我们按下标顺序往答案插入,即从前往后逐一确定在当前前缀中的排名等信息,详见例题。
1. AT_dp_t Permutation / UVA1650 数字串 Number String
实际上,对于
也就是说,题目并不关心这几个数是否真的是
设
如果这一位需要比前一位大(这一位是
如果这一位需要比前一位小(这一位是
2. P7986 [USACO21DEC] HILO P
发现当前这个数能不能报出 HI 或者 LO 和他在前缀中的排名有关,于是考虑按下标插入。
设
这也是种常见的辅助数组状态设计,当可以计入答案时,再将
- 当前插入数
,HI 转移至 LO,此时要求插入的数在 中排名最大,并且此时 对 有贡献,因此:
- 当前插入数
,LO 转移至 LO,此时不需要考虑当前数是否增加了新 LO,排名任意:
- 当前插入数
,LO 转移至 LO,说明当前插入数想加入 HI,但是失败了,即排名并非最小:
剩下三种转移至 HI 也是一样的,但是 LO 转移至 HI 对
状态数
类型二
此类型中,我们按值以一定的顺序(如从小到大)加入到答案中,此时又有两种情况:
考虑插入的位置进行转移。
记录某些关键点的信息,预定最终排列这些关键点上的值记为状态。
1. CF1806D DSU Master
面对稀奇古怪的题面,要尝试进行数学转换使其形式化。
在本题中,考虑最终排列
设
当
当
答案即为
2. P5999 [CEOI2016] kangaroo
这是一个经典的按段数的插入 DP,特点是可以看作当前状态是答案从左往右,依次组成若干段合法的答案,相同段数的多种情况没有区别,而每次插入数,都是往某一段的两端插入,DP 记录了段数为状态。
设
状态是什么意思呢?比如对于上面 T1,现在求出三部分答案区间:
对于这样的状态,一般有三种操作:
- 随便挑一段区间将第
个数接到它的结尾:
- 自己开一段区间,由于这一段区间可能插在上一个状态的
段形成的 个空(包含序列两端也可以插入)中的任意一个空中,所以:
- 合并左区间和右区间,自己放到中间,上一个状态的
段只有 个“中间”(序列两端的,显然不能合并),所以:
回到这一题。这道题的本质是求上面 T1 中的
用同样的方法设状态,从小到大考虑插入每一个数。
不存在第一种操作,因为从小到大考虑,要是个个数都直接往前面序列的后面接,必然会形成一个完全单调递增的“答案序列”,和题意不符。
第二种操作必然合法,它新开一段区间,前后都没有数,没有大于小于的比较。
第三种操作必然合法,因为从小到大考虑,现在考虑的数肯定比之前的数都要大,把自己放到中间合并任意两个区间,都能构成以自己为中心的
。
3. CF1437F Emotional Fishermen
考虑从大到小将
考虑记录排列第一个位置的值
于是 DP 即可。
时间复杂度