持续更新——dp的一些技巧

共菜鸡笔者看的……会慢慢更新,也请看到的大佬留意一眼,指出不足。

  • 对于一些对部分点的二维\(dp\),状态从左上角继承而来时,对于一个点\((x,y)\),对它编号\(x*m+y\),按照这个顺序\(dp\),可以保证更新当前值之前前面的已经被更新。

  • 善于发掘题目的性质。对于一些一眼看上去没法\(dp\)的东西,观察题目条件,将无用的状态去除或者确定一种\(dp\)顺序之类,变成一个经典的\(dp\)模型。

  • \(dp\)柿子写完,观察其中有没有类似\(i*j\)项的东西,看是不是能够斜率优化。推柿子原则:\(y\)是所有与\(j\)有关的项,\(k\)\(i*j\)项中与\(i\)有关的部分,\(x\)\(i*j\)项中与\(j\)有关的部分,\(b\)是只与\(i\)有关的部分。

  • 斜率优化的时候,观察题目要求的是\(\text{max/min}\)\(b\)项的\(dp[i]\)的符号,这些是决定凸包方向的重要条件。

  • 斜率优化的时候特别留意决策单调性,如果斜率单调,我们可以做到\(O(n)\)维护决策点;有一些不单调的(比如斜率),就要考虑其他维护决策点的方法。

  • 赋值初始值能不用\(\text{memset}\)就不用……

  • \(dp\)前捋清方程,推柿子的时候千万注意符号,如果反了就完了

  • 注意树形\(dp\)时,有些走向是从叶子到上面的,这时状态中如果需要有“距离最近的节点”之类,需要记录\(dfs\)到这里的祖先,只有祖先可以转移。

  • \(dp\)注意转移的顺序,一定要从之前没有更新的旧状态来更新当前的新状态,否则会错。

  • 对于一些\(dp,\)做完当前层是需要把一些\(dp\)状态合并掉来方便上面层继续\(dp\)的。

  • 在设 \(dp\) 最大值的时候一定要注意不要把类型上界卡得特别满,否则很容易溢出错误。

  • 计算方案数的时候留意一下不要把计算方案数写成取 \(\max\)\(\min\)

  • 树形背包写刷表会更快。因为枚举上界缩小了。

  • 写之前一定要把思路捋清楚 要不然会很惨……

  • 检查的时候要贴合 \(dp\) 的实际意义,不要写出不符合实际意义的方程式。

  • 注意背包一类的 \(dp\) 降维后的方程转移有没有后效性影响,一般会再记录一个辅助数组来记录上一次转移的 \(dp\) 值是最稳的。

  • 写大 \(dp\) 像麻将一类的时候一定要心平气和,封装函数,让 \(dp\) 部分尽量清新。

  • 计算某种情况的贡献的时候,考虑这个局部你计算的答案到底是这个局部的还是对于全局的,不同的计算方式与题意差别很大。

  • 区间 \(dp\) 有两种不同的转移,一种是枚举断点合并,一种是左右端点慢慢扩展。第二种情况的复杂度是 \(O(n^2)\) 的。而且往往需要证出来第二种是对的。某些题目数据范围较大而看着像区间 \(dp\) 的时候就想想这种转移。

  • 对计数类 \(dp\) 如果要求求一个串的不同方案能够匹配,不要光考虑已知部分的自相拼接。这样很容易导致算重。也就是说,我们应该尝试去对要构造的目标来 \(dp\) 以达到不会算重的目的,写的时候一定要思路清晰,否则有时候自己的方程会算重到了写完代码才反应过来。

  • 看到数据范围很小,先考虑状压;某数据范围很大可以考虑矩阵加速。

  • 对于一类需要枚举子集中 \(1\) 的位置来转移的 \(dp\) 可以用 lowbit 做到一个 \(\frac{1}{2}\) 的常数优化。因为原本枚举的是所有位置现在变成只枚举 \(1\) 的位置了,常数少了一半。卡常题要用。

  • 状压 \(dp\) 数据范围大的时候一定要警惕,任何一点点大常数的东西放到转移里面都会让效率大大降低。

  • 输出中间变量要在 \(dp\) 完了再输出……别还没 \(dp\) 就输出了……

  • \(dp\) 不要忘记转移条件……

  • 注意枚举顺序,像背包压维、滚动数组一类的转移顺序都是严格需要注意的。一定不要有后效性!

  • 对于斜率优化的柿子 有一种更方便的维护办法 不需要考虑单调性一类的,只需要带上一个 \(\log:\) 考虑把方程写成 \(f_i+constant_i=k_j\times i+constant_j\) 的形式,那么这样我们就把传统斜率优化的柿子中把 \(j\) 看成点变成了把 \(j\) 看为以 \(k_j\) 为斜率的一条直线,那么对应查询就是直接查询过点 \(i\) 的直线最值。这个东西可以很系统化地用李超树来维护。

  • 对于传统斜率优化实际就是把每个点和它的 \(f_i\) 等看成一个坐标系,而转移的时候斜率固定 \(c_i\) ,然后查询所有决策点对应这个斜率的最小/最大截距。

  • 计数类 \(dp\) 注意是否要乘组合数 如果带着不方便转移就考虑在计算的时候直接把最后计算的除掉 到最后直接乘组合系数

持续\(\text{update……}\)

posted @ 2020-05-03 00:23  Refined_heart  阅读(355)  评论(0编辑  收藏  举报