计数dp与容斥
Posted y_dove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计数dp与容斥相关的知识,希望对你有一定的参考价值。
本文参考自[彭博-问题的常用技巧]
I.条件计数
- 问题最难的点一般有两种途径,不重不漏的计数和容斥,如果要不重不漏的计数就要寻找一个唯一能表示计算的目标的量
1.CF1264D2
递归定义合法括号序列及其深度:
• 空串是合法括号序列,深度为 0 。
• 如果 s 是合法括号序列,那么 (s) 也是合法括号序列,深度
为 s 的深度加一。
• 如果 s,t 是合法括号序列,那么 st 也是合法括号序列,深度
为 s,t 的深度的较大值。
定义任意一个括号序列的深度为其所有合法括号子序列的深度的
最大值。
给出一个包含 ()? 的字符串,? 可以任意替换为) 或 ( ,求出每
一种替换方案的深度之和。
\\(n ≤ 10^6\\)
solution
考虑假设我们已知一个括号序列(不一定合法),如何计算其深度
可以发现最优方案一定包含一个((((((((......))))))))的形式,满足左括号和右括号数相等且一一对应
容易想到枚举中间的那个位置,然后算一下即可
2.AGC052C Nondivisible Prefix Sums
给定质数 P 和长度 n 。
对于 \\((P-1)^n\\) 个值域在 \\([1, P-1]\\) 的数列,称它是好的,当且仅
当存在一种方法把它重排,使得每个前缀和都不是 P 的倍数。
求好的数列个数。
\\(1 ≤ n ≤ 5000, 3 ≤ P ≤ 10^8\\)
solution
AGC yyds!很妙的题
首先如果和是 P 的倍数,那么一定不行
我们考虑这么一种构造方法
每次取剩余出现次数最多的数去填,不行就换次多的,注意到这种方法会不合法当且仅当后面填 x 不合法且数列中仅剩 x
注意到根据这种方法,如果众数出现次数\\(\\leq n / 2\\),那么一定合法,这个可以用数学归纳法证明
我们考虑将众数消到\\(\\leq \\frac{n}{2}\\),不妨设众数为1(如果不是就所有数都乘以逆元),我们考虑一直填 1 ,如果不行就换一个数,注意不行是,前缀和必然为 \\(P-1\\) ,如果此时填 \\(a_i\\) ,那么还能填 \\(P-a_i\\) 个 1 ,那么如果 \\(cnt1 \\leq \\sum_i(P - a_i)(a_i != 1) + P - 1\\),则必然可以
反之,若不满足,则将所有数都消耗完依然剩下1,那么必定不合法
得到充要条件后,因为无法同时记录\\(\\sum_i a_i \\bmod P\\)和\\(\\sum_i (P - a_i)\\),我们不妨计算钦定总和不为 P 的倍数且不合法的方案数,那么\\(\\sum (P -a_i) < n\\),做一下背包即可,最后用总数\\((P-1)^{n-1}*(P-2)\\)减去背包方案的 P - 1倍即可(因为我们强行钦定众数为 1 )
3.[AGC043D] Merge Triplets
题意简述:
-
给定 n ,求长度为 3n 的能被以下方法生成的排列个数。
-
生成 n 个长度为 3 的数列,使得每个 1 到 3n 中的数恰好被用一次。
-
生成一个初始为空的数列 P ,重复以下操作 3n 次:
-
在所有非空数列的开头中选取最小的元素 x 。
-
把 x 加入到 P 的末尾,并从原数列删去。
\\(n ≤ 2000\\)
首先我们思考假设我们已经有数列了该如何生成 P
必然是归并排序,模拟归并排序的过程,就是按照前缀最大值分成若干个长度为1/2/3的段
,然后整段按照前缀最大值从小到大排序
那么我们可以改写题意,称一个排列 P 是合法的,当且仅当它可以被分成若干个长度为 1 / 2 / 3的段,段首单调递增,且一的段个数要大于二的段的个数
倒过来 dp ,设 \\(dp_{i,j}\\)表示 dp 到 i ,第一个段个数比第二个段多 j
因为最后一段段首必然是全局最大值,根据这个转移即可
总结:
大概分析一下这种条件计数不重不漏的方法(即不包含容斥)
-
先分析题目性质,思考构造过程
-
根据构造过程,转化题意,寻找更简洁的充分条件(难点)
-
根据充分条件 dp (基本功)
分析性质,转化题意这一步在很多其他题目中都有应用,基本功也是必须掌握好的
II.容斥
1.AGC041F
题解:solution
2.ARC096E
套公式仔细分析即可
简单题,但是有一点要注意,只包含空集的集合不是空集
以上是关于计数dp与容斥的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 4818: [Sdoi2017]序列计数容斥原理+dp+矩阵乘法