DP特训总结(技巧篇)

· · 个人记录

像题解/游记一样的东西挂在这里了。

这里就主要写 DP 技巧了。

1.插入 DP

应该是之前听说过的东西?差不多忘掉了,想了很久才想起来。DP 特训里有两道插入 DP 的题,评讲之前都没做出来,所以专门开了一个技巧来写这个东西。

具体来说,插入 DP 可以用于处理如下问题:

因为要求元素不重复,那么直接 DP 就比较困难。所以考虑依次插入每个元素以达到相同效果。更具体地:

总而言之,有点像区间 DP,是一个很有用的技巧,而且特征比较显著?以后可以看到这种元素不重复就往插入 DP 上想。

2.树形 DP

树形 DP 应当是很熟悉了。但是看 DP 特训的 C 题时发现首先想到的是换根而不是在 LCA 处合并路径,貌似又有点生疏了。

所以这里提到的是一类树形 DP,即处理树上路径信息的树形 DP。对于这种东西,一般有两种做法,换根与 LCA 合并。

如果能在合理复杂度内确定出有根树的 DP 值,并且转移只和父节点和子节点相关(应该是吧?好像暂时没见过其它的。但是理论上和整棵子树相关也是可做的,这里就先只讨论这种情况),那么就可以考虑换根。如果转移是可逆的运算,例如乘法或加法,那么尝试掉某棵子树的贡献就行了。但是如果是 \min\max 之类的运算,就可能要维护次值来进行子树贡献的删除。可能会有点恶心,但是熟练掌握后还是很好用的,优点是不用动脑子(有时候可能还要上点数据结构)。

LCA 合并就是类似于 DP 求直径之类的东西。这个东西情况不同处理起来也不同,但是呢一般来说都是处理一个向子树内的链的和一个从子树上来的链。还要保证这两个东西不能重合的话,取前缀 \max 合并一遍再倒着合并一遍就行了,主要是看方向有没有影响。这玩意的优点是......好像没啥特别的优点,可能实现比较简单并且常数小吧?思维难度感觉是和换根差不多的。

树形 DP 的记忆又重拾起来了。特训赛上没做出来 C 的原因是我竟然忘了可以维护次值......好像还是得多练一点才行。

3.容斥

很不要脸地把自己题目的技巧写上去了(什么)。

借用一篇题解里的话就是,用一堆至少容斥出恰好

当发现一个转移会算重的时候,不要慌张,观察其算重是否有规律,如果发现它被选中的每一个点的每一种组合都会被算重(这里可能有点抽象,意思是假如 \{1,2, 3\} 是被选中的,并且还可以发现算出的 \{1\},\{2\},\{3\},\{1,2\},\{1,3\},\{2,3\} 的情况都会把 \{1,2,3\} 的算到),那么可以尝试去容斥它。具体做法就不细说了,但是可以从举的例子里发现这种容斥一般适用于这样的状态:

然后如果是所有方案数一个 1,-1,1,-1\dots 的容斥即可统计出正确答案,这里的证明二项式定理/反演即可,不再赘述。如果是恰好 k 个直接组合意义暴力维护,也不再赘述(类似于上面的注意中的例子)。

大的技巧已经写的差不多了,当然还有一点小技巧。

总结的总结

总而言之,这次 DP 特训真的是收获满满。大家选的题都非常优质,我也学到了很多技巧。虽然自己下去还得练,但是应该不会再像以前那么吃力了。那么,希望我的 DP 水平可以提升起来,拥有稳定切紫题的水平!

我们都有光明的未来。