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 个点从队尾入队(对后面来说新的决策) .
-
k不确定正负, 此时不能弹出队首, 但是仍然可以维护单调性, 二分查找来弥补, 时间复杂度 O(NlogN) .
- 决策点的横坐标不单调递增, 需要在任意位置插入决策点, 待填坑 .