斜率优化
Cornessless · · 算法·理论
前言
芝士一个较为偏代数方面的斜率优化介绍。主要原因是较为懒得放图,凑活看吧(什么
虽然但是斜率优化并不是提高组考点,不过还是闲的没事写了介绍,是不是该祈祷考试时候可以拿来骗点分?
引入
在动态规划中,可能存在与
此时单调队列优化彻底尽力,需要使用斜率优化 qwq。
斜率优化
为了处理
首先,我们考虑分别从
为了方便后面递推,我们将
注意到,左边的柿子形如求坐标系中连接两个点的直线的斜率的柿子
把这个柿子拓展一下,对于任意一种可转移过来的状态
然而这还是
所以我们需要将其继续优化。
考虑三种状态
现在再考虑凸包上最优点,因为凸包上的斜率具有单调性,所以可以二分寻找第一个斜率满足小于
求
接下来我们考虑实现 qwq。
一般的斜率优化题,可以分为以下四种:
- 横坐标单调,斜率单调
- 横坐标单调,斜率不单调
- 横坐标不单调,斜率单调
- 横坐标不单调,斜率不单调
我们分别有不同的处理方法。
(注:借鉴了这篇文章的分类标准,加了一点实现方法)
1. 横坐标单调,斜率单调
考虑凸包的单调性和斜率的单调性是否相同,绝大多数可直接使用 vector 之类的线性数据结构维护,每次加入一个新点,每次更新把队首不符合斜率要求的元素弹出。
修改复杂度:
查询复杂度:
2. 横坐标单调,斜率不单调
使用单调队列维护。
保证队列内斜率单调,每次加入新点时若队列末尾两个点到新点的斜率不符合单调性,则将队尾弹出,查询使用二分查找。
修改复杂度:
查询复杂度:
3. 横坐标不单调,斜率单调
使用链表或 set 维护。
保证链表或 set 内斜率单调且按 x 坐标排序,加入新点时,二分查找横坐标对应位置,随后向两边拓展,将不符合单调性的点弹出,查询使用二分查找。
修改复杂度:
查询复杂度:
4. 横坐标不单调,斜率不单调
使用李超线段树,cdq分治或平衡树维护。
需要支持以下操作:
- 插入一个点
(x,y) ; - 删除一个点;
- 查询按
x 坐标排序时,(x,y) 的上/下一个下标; - 查询按
x 坐标排序时,第一个满足k_{i-1,i}\leq -C(i) \leq k_{i,i+1} 的i 。
修改复杂度:
查询复杂度:
例子
以 P3195 [HNOI2008] 玩具装箱 为例:
读题,容易想到令
则答案为
用前缀和化简,令
可以将
即
可以将
展开,得:
对应到一般公式,有:
故将每个状态
容易发现其为横坐标单增,斜率也单增的斜率优化 dp,使用单调队列维护凸包然后二分查找就可以勒。
更新日志
update 2024.7.10 : 开工
update 2024.7.11 : 没写完
update 2024.7.12 : 依旧没写完(
update 2024.9.16 : 仍然没写完
update 2024.11.8 : 终于写完乐(流出感动泪水
update 2024.11.10 : 审核打回重写 qwq
update 2024.11.25 : 二次打回 qwq
update 2025.7.20 : 疑似有误重改