(长期更新)DP 优化 学习笔记

  • 空间优化
  • 时间优化

  • 状态方面的优化
  • 转移方面的优化
    • 快速寻找决策点
    • 批量转移
      • 从一批状态转移来
      • 转移到一批状态

纯粹的空间优化

滚动数组 & 类似滚动数组的

本质:某个时刻,某些状态现在和以后都不会再被用到了,于是让新的状态覆盖掉这些状态。

滚动数组常用取模(特殊的:奇偶)来实现。

时间优化 & 时间和空间一起优化的(综合优化)

单调队列优化 DP

作用:去除多余点 来 快速寻找决策点。

状态转移方程:

\[f _ i = \min _ { l _ i \leq j \leq r _ i } f _ j \]

  • 可能还有 只与 \(i\) 有关的数值、其他只与 \(j\) 有关的数值 和 常数 参与运算。总之这些都是定值(\(j\) 走过了,\(f _ j\) 就成定值了)。
  • \(\max\)\(\min\) 同理,这里以 \(\min\) 为例。
  • \(l _ i\)\(r _ i\) 都随 \(i\) 增大而不降(这里假定是 \(f _ 1\)\(f _ n\),且 \(r _ i < i\))。

发现 \(l _ i\)\(r _ i\) 都是单调不降的,\(l _ i\) 右移相当于进队,而 \(r _ i\) 右移相当于出队。于是直接用队列来维护。

前面的点显然会比后面的先出队,那么如果后面的点已经进队了且比前面的点优,这个前面的点就永远不会作为决策点了,于是直接让它出队即可。发现这样的过程形成了一个从前往后单调递增的队列,它就是单调队列。出队的过程其实就是在队尾踢点直到踢不动。队头的点即是决策点。

在线。

斜率优化 DP

作用:去除多余点 来 快速寻找决策点。

单调队列优化 DP 无法处理 \(c _ i \times c _ j\) 这种与 \(i\) 相关的和与 \(j\) 相关的乘起来的情况。这时就需要斜率优化 DP。

状态转移方程:

\[f _ i = \min _ {1 \leq j \leq i - 1} a _ i + b _ j + c _ i c _ j \]

  • \(\max\)\(\min\) 同理。

下面两个方向都是在线(上面方程里和 \(j\) 有关的可以换成 \(f _ j\),总之走过了就变成定值了)。

有两个方向:

1. 李超线段树(维护直线)

应用范围更广,但速度稍慢。

去 min 推式子。

\[f _ i - a _ i = c _ j c _ i + b _ j \]

\[y = k x + b \]

把与 \(j\) 相关的作为直线信息,把与 \(i\) 相关的作为点的信息(直线 \(x = \ldots\)

应用范围更广,但修改 2 只 log,查询 1 只 log。

可以放到树上,李超线段树合并。

2. 队列(维护凸壳)

速度较快,但限制更多。

一些细节可能搞忘了,哪天复习来补。

\[b _ j = - c _ i c _ j + f _ i - a _ i \]

\[y = k x + b \]

把与 \(j\) 相关的作为点的信息,把与 \(i\) 相关的作为直线的信息。

相当于拿一根已知斜率的直线去过每个点,看截距的最小值。那么只需要从下往上移动这个直线,看第一个过的点是哪个。

[斜率 单增 / 单减 时,可以用单调队列来维护凸壳。斜率单增且取 \(\min\) 是维护下凸壳,斜率单减且取 \(\max\) 是维护上凸壳。总之就是考虑斜率单增还是单减,取 \(\max\) 还是取 \(\min\),四种情况,画图(也许也可以在脑子里想象出图)分析。](?)

[斜率没有单调性的时候也可能可以,只要点的横坐标有单调性就可以用队列维护凸壳,找决策点时在凸壳上二分。也要注意思考是上凸壳还是下凸壳。](?)

[实现细节上,队列要保证一定有一个点在里面。](?)

[要注意开始的时候那个位置 \(0\) 的取值,不一定直接是 \(0\),要为了之后得到正确的值而取值。](?)

还有关于精度、[\(0\)](?????;斜率?????)的问题,待补。

听 xjy 说推出来的式子可以不止一种,只要斜率单调即可。

单调队列优化 DP、斜率优化 DP 的观察技巧

  • 拆式子,变成能进行这两种优化的形式。
  • [换 维度枚举顺序。](?)

2024.?.?
2024.10.23

posted @ 2024-10-09 16:53  huangkxQwQ  阅读(3)  评论(0编辑  收藏  举报