-
斜率优化的作用
Fi=min( Fj+si2+(sj+L)2−2si(sj+L) )
形如这个式子 关于i的项 与 关于j的项 混杂(相乘) 的状态转移方程, 可以使用斜率优化来加速 .
接下来以优化这个式子为例说说斜率优化.
-
斜率优化的内容
将上方给出的式子去掉 min, 仅关于 j的项放在左边, 关于 i的项放在右边得 ↓
Fj+(sj+L)2=2sisj+Fi−si2+2Lsi
这个时候原式为 y=kx+b 的形式, 其中
- y=Fj+(sj+L)2
- k=2si
- x=sj
- b=Fi−si2+2Lsi
∵j∈[1,i) 且为一个单调递增的正整数数列
∴x,y都随 j 单调递增.
又 ∵k 始终不变
∴ 上式代表了一个 斜率不变, 随着经过点 (x,y)的变化, 截距也随之变化的直线 .
暂且称 (x,y) 代表的点为 决策点,
由于单调递增, 决策点 构成的图象为 下凸壳 , 这里给出概念图.
备注: kbc<kcd .
我们需要 截距 b 最小进而使答案最优, 即找到一个最优的 决策点 .
找到第一条斜率大于k的线段,过左端点的直线截距即为最小值.
-
斜率优化的实现
使用 单调队列 维护, 没学过的可以看 这里 了解一下,
具体地说:
对上转移方程, 应当维护斜率从队首到队尾的单调递增队列,
设当前是第 i 个点,
- 不断弹出队首, 直到 队首 与 次队首 的斜率大于等于 k 或 队列长度为 1 , 队首即为当前最优的 决策点 .
- 不断弹出队尾, 直到 队尾 与 次队尾 的斜率小于 次队尾 与 i 的斜率, 将第 i 个点从队尾入队(对后面来说新的决策) .
时间复杂度 O(N) .
经典例题
-
斜率优化的变形
- k不确定正负, 此时不能弹出队首, 但是仍然可以维护单调性, 二分查找来弥补, 时间复杂度 O(NlogN) , 例题 , 下有数学解释 .
- 决策点的横坐标不单调递增, 需要在任意位置插入决策点, 待填坑 .
-
相关数学推导补充
以 该题 的式子为例, (已经去掉 min),
F[i]=F[j]+st[i]∗(sc[i]−sc[j])+S∗(sc[N]−sc[j])
设 决策 j 比 决策 k 优, 则
F[j]+st[i]∗(sc[i]−sc[j])+S∗(sc[N]−sc[j])<F[k]+st[i]∗(sc[i]−sc[k])+S∗(sc[N]−sc[k])
化简得
sc[j]−sc[k]F[j]−F[k]<S+st[i] .
若 st[i] 单调递增, 则 j 在以后不可能比 k 更优了, 所以可以执行弹出队首的操作 .
否则 j 可能在以后的某一个决策中比 k 更优, 不能直接弹出队首 .