斜率优化 DP 核心推导与笔记

斜率优化 DP 核心推导与笔记

一、适用形式

DP 转移方程可写成:

\[dp[i] = \min_{j < i} \{ f(j) \cdot g(i) + dp[j] \} + h(i) \]

或最大值形式:

\[dp[i] = \max_{j < i} \{ f(j) \cdot g(i) + dp[j] \} + sum \]

核心特征:\(f(j)\) 只与 \(j\) 有关,\(g(i)\) 只与 \(i\) 有关,两者以乘积形式出现。

二、点视角的转化

2.1 设点坐标

令:

\[x_j = f(j),y_j = dp[j] \]

原式中需要最小化的部分为:

\[f(j) \cdot g(i) + dp[j] = g(i) \cdot x_j + y_j \]

\(E = g(i) \cdot x_j + y_j\),我们要求 \(\min E\)

2.2 转化为几何问题

考虑一条斜率为 \(-g(i)\) 的直线:

\[y = -g(i) \cdot x + E \]

当它过点 \((x_j, y_j)\) 时,截距为:

\[E = y_j + g(i) \cdot x_j \]

这正是我们要最小化的值。

所以,我们本质上就是要最小化 \(E\) 的值。

几何操作:用一条斜率为 \(-g(i)\) 的直线,从 y 轴负无穷远处(\(E\) 极小的方向)向上平移,它碰到的第一个点,就是使截距 \(E\) 最小的点。

如图,我们感性理解发现我们维护一个下凸壳(蓝色部分),所有不在下凸壳上的点一定会被包住,当直线从下放向上平移时,一定会优先碰到下凸壳上的点,所以所有不在下凸壳上的点就全部可以丢掉了。

因此总结:所有可能的最优解,都在点集的下凸壳上。

所以我们可以发现

\(\min\) → 斜率为 \(-g(i)\) 的直线从下往上碰 → 维护下凸壳

\(\max\) → 斜率为 \(-g(i)\) 的直线从上往下碰 → 维护上凸壳

然后我们可以发现几个性质:

  • 加点的过程只依赖已算出的 \((x_j, y_j)\),只看点之间的几何位置关系,完全不关心 \(g(i)\) 是什么。
  • 凸壳一旦维护好,对于后续任意查询斜率 \(-g(i)\),最优解一定在凸壳上,且可以高效定位。
  • 凸壳就像一个建好的索引,查询什么值都保证返回正确结果。

因此可以用二分查找在凸壳上定位最优点。

若查询斜率也单调,可用单调队列\(O(1)\) 时间内维护队首。

三种情况的复杂度

条件 方法 复杂度
\(f(j)\) 单调,\(g(i)\) 单调 单调队列 \(O(n)\)
\(f(j)\) 单调,\(g(i)\) 不单调 单调栈 + 二分 \(O(n \log n)\)
\(f(j)\) 不单调,\(g(i)\) 不单调 李超线段树 / CDQ 分治 \(O(n \log n)\)
posted @ 2026-07-21 20:12  MistyPost  阅读(8)  评论(2)    收藏  举报