### 斜率优化简介
**问题引入**
给定一个长度为 的序列 ,连续若干个数可以分为一组,将这些数分成若干组,每一组的代价为组内元素和的平方,要求最小化代价
**朴素算法**
设 表示将前 个数分组之后的最小代价,那么有转移方程
如果我们将后面那个平方项拆开,那么会出现 这样的同时包含两个变量的项,这就意味着我们将无法采用上面单调队列的方法来优化它,这时候我们就要引入斜率优化了
**基本概念**
就是把决策与决策之间写成一个类似斜率 的式子,然后对其单调性进行分析,用队列维护决策
### 任务安排1 (费用提前计算+斜率优化)
**题目**
有 个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变。
机器会把这 个任务分成若干批,每一批包含连续的若干个任务。
从时刻 开始,任务被分批加工,执行第 个任务所需的时间是 。
另外,在每批任务开始前,机器需要 的启动时间,故执行一批任务所需的时间是启动时间 加上每个任务所需时间之和。
一个任务执行后,将在机器中稍作等待,直至该批任务全部执行完毕。
也就是说,同一批任务将在同一时刻完成。
每个任务的费用是它的完成时刻乘以一个费用系数 。
请为机器规划一个分组方案,使得总费用最小。
**题解**
设 表示前 个任务分成 批时的最小费用
时间复杂度 ,我们无法接受
这时候我们可以采用一个经典套路:费用提前计算
就是说,我们在执行一些任务的时候,我们不方便知道这个机器在之前启动了多少次,因此需要记一个状态 ,但我们知道当前机器的费用是会在后面每一个机器中算到的,因此采用和关路灯和基站选址相同的方法,我们可以这么做:
设 表示把前 个任务分成若干批次,并且加上每一批造成的后续影响的最小费用。
转移方程如下
但是这样依然无法通过本题,所以下面开始进行斜率优化
我们先对状态转移方程进行变形,先将与 有关的项提出来
去掉 ,将与 有关的量视作是变量,有
那么这个东西就变成了一个以 为斜率, 为截距的直线,同时,每一个决策 都对应着二维平面上的一个点 。
同时, 与其对应的直线在平面上的截距有关,斜率是固定的为 ,于是我们知道,截距越小, 就越小,直观来讲,就是平面上有一堆的点,然后你现在要拿着一个斜率固定的直线去卡到点集的最低位置,那个就是当前状态 的最优决策
我们考虑如何来快速找到这个最低点,设 ,由于 都是正整数,所以这里有
给出结论, 能够是最优决策,当且仅当
几何意义就是 处在点集的下凸壳上,换句话说,对于这道题而言,只有处于下凸壳上的点才有可能成为最优决策点
综上,我们可以建立一个单调队列 来维护这个下凸壳,队列中存储对应的决策,然后对于每个状态 :
1. 检查队头的两个决策 , 如果其所对应的斜率 ,那么就让 出队,因为其对应的点一定不是直线 与下凸壳的切点(画图理解)
2. 取队头 作为最优决策,算出
3. 将新决策 插入队尾,利用上面给出的判定可能最优决策的条件,维护队列的单调性
时间复杂度
### 任务安排2 (状态斜率不单增的斜率优化)
**题目**
同任务安排1,区别在于
**题解**
可以取到负值,说明我们上面所提到的状态直线斜率变化不在具有单调性,这时候我们可以直接用单调队列先维护出整个下凸壳,然后对于每一个状态,利用二分查找,找到左边斜率比它小,右边斜率比它大的分界点,即最优决策点
时间复杂度
### 任务安排3 (决策点横坐标不单增的斜率优化)
**题目**
同任务安排2,同时再更改一个条件 可能是负数
**题解**
这道题把 的单调性也做掉了,由于状态 只能从比它小的状态 转移过来,因此我们考虑在这种情况下如何动态维护下凸壳
假设我们现在想要插入一个决策 ,它的坐标为 , 画个图模拟一下,我们发现决策 的加入会替代掉原下凸壳的一段连续的决策(或者不替代),所以我们可以考虑从决策点 处向左右两侧进行二分,向左找到第一个斜率比它小的边,向右找到第一个斜率比它大的边,然后从下凸壳中删除掉我们选出的这一段决策点(这里通过平衡树维护),最后通过任务安排2的方法寻找当前状态 的最优决策点即可
由于每个决策点至多只能加入删除一次,因此时间复杂度是 的
### CF311B 猫的运输 (二维dp的斜率优化)
**题目**
他养了 只可爱的猫子,雇佣了 个铲屎官。这里有一条又直又长的道路穿过了农场,有 个山丘坐落在道路周围,编号自左往右从 到 。山丘 与山丘 的距离是 米。铲屎官们住在 号山丘。
一天,猫子们外出玩耍。猫子 去山丘 游玩,在 时间结束他的游玩,然后在山丘 傻等铲屎官。铲屎官们必须把所有的猫子带上。每个铲屎官直接从 走到 ,中间不停下,可以认为不花费时间的把游玩结束的猫子带上。每个铲屎官的速度为一米每单位时间,并且足够强壮来带上任意数量的猫子。
你的任务是安排每个铲屎官出发的时间(可以从 0 时刻之前出发),最小化猫子们等待的时间之和。
对于全部的数据,满足 ,,,,,。
**题解**
首先对于每一只猫,我们可以计算出什么时候可以刚好将它接走,我们将这些时间存在一个长度为 的数组 当中,将 从小到大排序,记 数组为 数组的前缀和
这时候有一个显然的贪心策略是,每个人需要带走 数组中一段连续区间的猫才有可能最优
这样问题就转化成了,将一个长度为 的序列分为 段,每一段的花费是该段的最大值与其他所有值的差值之和,求最小代价
设 表示考虑到第 只猫,已经划分了 段时的最小代价
由此我们得出转移方程如下:
我们先忽略掉 这一维,那么转移方程就是
这显然可以进行斜率优化,直线斜率是 ,决策点坐标是 , 值都是正的,按照任务安排1去维护下凸壳即可
对于段数的限制,我们可以考虑外层枚举状态 ,内层从小到大枚举划分段数 按照转移方程进行转移即可
时间复杂度
### P3628 [APIO2010] 特别行动队 (上凸壳斜率优化)
**题目**
你有一支由 名预备役士兵组成的部队,士兵从 到 编号,你要将他们拆分成若干特别行动队调入战场。出于默契的考虑,同一支特别行动队中队员的编号**应该连续**,即为形如 的序列。所有的队员都应该属于且仅属于一支特别行动队。
编号为 的士兵的初始战斗力为 ,一支特别行动队的初始战斗力 为队内士兵初始战斗力之和,即 。
通过长期的观察,你总结出对于一支初始战斗力为 的特别行动队,其修正战斗力 ,其中 是已知的系数()。 作为部队统帅,现在你要为这支部队进行编队,使得所有特别行动队的修正战斗力之和最大。试求出这个最大和。
,,,,。
**题解**
我们定义 数组是 数组的前缀和,设 表示将前 个士兵分组后的最大和,那么有转移
然后我们得到状态 的斜率是 ,截距是 ,对于决策 ,它在二维平面上的点为
由于这道题是取 ,我们改成维护上凸壳即可
时间复杂度
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】