计数DP总结
动态规划-计数类-总结
计数类的题,一般都需要用到排列组合的知识,较常用的有阶乘、组合数(一般必不可少)、容斥原理、全集-补集=所求集。
背包类
母题
本题虽然简单,但是却无意间将计数类 DP
与背包结合在一起,状态 \(f[i][j]\) 表示用前 \(i\) 个数选到 \(j\) 的方案数,每个数可选无限次,完全背包模型。
变式
本题本质上还是类似的状态,可以用 \(f[k][i][j]\) 表示步数、坐标。但是我们可以发现我们不在乎到底在哪里,只要知道与终点是不是在同行/同列即可,然后就可以进行优化状态,转移用到组合数。所以本质上就是对于状态的优化。
本题需要分类讨论。设 \(a\) 个1,\(b\) 个-1,若 \(a\le b\),当作像隔板法一样用组合数特判。否则,就和母题差不多了。
由于都是×3或÷2,所以选出的数不可能出现相等的情况,也就不用管重复了。令 \(f[i][j]\) 表示选择了 \(i\) 个数之后,结尾的数为 \(j\) 是否存在,数很大,配合哈希表。本题不是严格的 DP
,但是状态跟母题还是一样的。
关键在于大于等于4的连通块。发现这样求不容易,所以我们应该反着求,于是我们的状态里可以包含一个点、双连通块、三连通块。第一维固定,后面我们只需记录两维,那么其中一种连通块的个数就可以求出,然后组合数分类讨论。
我们只关注状态,发现状态还是很普通,第二维维护的是最大值,然后使用前缀和优化。
-
发现 \(k\) 很大,于是考虑如果
DP
,可能要矩阵乘法优化。发现不好优化,那我们尝试转换角度。先对 \(n\) 进行一次常规的DP
(注意去重),然后发现这个东西是可以贪心的,用求得的DP
数组计算。 -
本题应用了nim游戏的结论,但是可扔掉,发现只要扔掉的异或和等于原异或和即可,于是题意就进行了转换。然后又回归到母题经典的状态,注意本题还有一个关键的点就是一个数与比它小的数异或不会超出其二倍(异或的性质)。
-
本题的难点在于算重,所以关键就是假定一个顺序(即尽量靠左,可称作紧)。
-
与过河卒/数字三角形的转移类似。
-
[ABC311F] Yet Another Grid Task
在于条件的转换,通过对原网格进行变形,将它拉成一个平行四边形,即将给定的网格向下推,使其左上角斜向变形。将下、右下变为右、下。
-
prufer序列+圆排列
由于是序列型,所以一位是前 \(i\) 个字符,发现 \(k\) 小,所以直接用第二维达到 \(2^k\) 表示最后 \(k\) 个的字符,然后是一些预处理。
规律
发现状态的表示无非是第一维是前几个数/点(\(i\)),后几维是维护的属性的值(看题目中的信息,有些时候是和/最值,还有可能是某种特定东西的数量)。注意观察题目中特别小的数(比如连通块的大小为 \(3\)、树的度 \(<3\)),可能都可以作为状态的一维。
难点一般在抓住题目中关键信息设计后面一到两维状态、组合数的转移、去重(可以自定义一个顺序,就是某种规则下的答案)、等价变形(题意、条件)。
计数 DP
可能作为算法的一部分,或同时是其他各种 DP
模型。
还有部分小技巧(贪心、异或性质等)。
特征
题目要求统计个数,而且个数一般极大。