计数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

套公式仔细分析即可

简单题,但是有一点要注意,只包含空集的集合不是空集

posted @ 2021-06-05 00:49  y_dove  阅读(207)  评论(1编辑  收藏  举报