2025dsfz集训Day12: 斜率优化DP
Day12:斜率优化DP
一次函数与斜率
- 斜率:表示一个直线倾斜程度。定义为和正方向水平轴的夹角的正切值。
- 经过两个点 \((x1, y1)\) 和 \((x2, y2)\) 的直线的斜率为 \(\frac{y2−y1}{x2−x1}\)。
(保证这两点不重合) - 可看出过两个竖直的点的直线斜率无定义。需特别关注。
证明:
将 \(x1,x2,y1,y2\) 带入同一个函数解释式得:
\]
其中,\(k\)为斜率,\(d\)为节距.
将两式相减可得:
\]
移项可得:
\]
得证.
例题1:[一本通]打印文章
输入长度为 \(n\) 的非负序列,输入权值 \(M\),把序列划分为若干连续段,每段的价值为这段权值和的平方加 \(M\),求一种划分方式,使得每段价值之和最小。
- \(n ≤ 500000\)
设 \(dp_i\) 表示前 \(i\) 个数的最佳答案。考虑枚举倒数第二段的右端点 \(j\),写出转移式为:
\]
- 尝试优化,令 si 表示前缀和,则转移式为:
\]
\]
- 有 \(2s_is_j\) 让含 \(j\) 项和含 \(i\) 项无法分开,无法直接数据结构优化。
- 设 \(res_j = M + s_i^2 + dp_j + s_j^2 − 2s_is_j\),表示从 j 转移到 i 的值。显然,\(dp_i=min_{j=0}^{i-1}res_j\)
\]
- 若把 \(P_j(s_j, dp_j + s_j^2)\) 看作二维平面上的一个点?
- 则直线 \(y = (2s_i)x + (res_j − M − s_i^2)\) 一定过 \(P_j\)。且此直线斜率固定为 \(2s_i\),纵截距为 \(res_j − M − s_i^2\)。
- 对于固定的 \(i\),求 \(res_j\) 中的最小值,转化为:给定若干个 \(P_j\),求过每个点斜率为 \(2s_i\) 的直线的截距最小值。
下凸壳
直观理解: 只有所有的 \(P_j\) 里“最靠下”的点有可能成为答案。如何定义“最靠下”?
- 我们定义“不靠下”的点:
- 点集中两个点 \(A(x_A, y_A), B(x_B, y_B)\),若满足 \(x_A = x_B\),且 \(y_A < y_B\),则 \(B\) 是“不靠下”的点。
- 点集中三个点 \(A(x_A, y_A), B(x_B, y_B), C(x_C, y_C)\),若满足 \(x_A < x_B < x_C\),且 \(k_{AB} > k_{BC}\),则 \(B\) 是“不靠下”的点。
- 称剩余不是“不靠下”的点形成的点集为:下凸壳。
- 只有下凸壳上的点可能成为最优转移点 \(res_j\)。
- 证明:一个“不靠下”的点,第一种情况显然不可能。
- 第二种情况,即这个电是 \(P_A, P_B, P_C\),其中 \(s_A < s_B < s_C\),且 \(k_{AB} > k_{BC}\) 中的 \(P_B\) 点。直接放缩可证明 \(k_{AB} > k_{AC} > k_{BC}\)(三弦引理)。
- 先考虑两个转移点 \(P, Q\)。
- 当 \(2s_i < k_{PQ}\) 时,\(P\) 比 \(Q\) 优。
- 当 \(2s_i ≥ k_{PQ}\) 时,\(Q\) 比 \(P\) 优。
- 当 \(2s_i < k_{AC} < k_{AB}\) 时,\(A\) 比 \(B\) 优。
- 当 \(2s_i ≥ k_{AC} > k_{BC}\) 时,\(C\) 比 \(B\) 优。
- 所以无论何时,\(B\) 一定不是最优转移点。
实现方式
- 实现方式:用单调队列维护下凸壳。每在右边(\(s_i\) 单调不降)加一个新点,按照斜率单调递增的原则维护单调队列。每次求 \(dp_i\) 时,在左侧弹掉斜率小于 \(2s_i\) 的点,则队头为切点。时间复杂度为 \(O(n)\).
- 转移式为 \(1D1D\) 形式,形如 \(dp_i = min_j\{F(i) + G(j) + H(i) × R(j)\}:\)
- 转化为 \(G(j) = (−H(i)) × R(j) + (resj − F(i))\)
- 再转化为,二维平面上有若干点 \(P_j(R(j), G(j))\),用斜率为 \(−H(i)\) 的直线去过这些点。最小(大)化纵截距,
- 维护下(上)凸壳解决。
上一道题满足了 \(R\) 函数是单调不降函数,这让我们可以直接用队列维护下凸壳。而且满足了 \((-H)\) 函数是单调不降函数,这让我们可以用单调队列直接把队头弹掉。
[一本通] Cats Transport
小 \(S\) 是农场主,他养了 \(M\) 只猫,雇了 \(P\) 位饲养员。农场中有一条笔直的路,路边有 \(N\) 座山,从 \(1\) 到 \(N\) 编号。第 \(i\) 座山与第 \(i − 1\) 座山之间的距离是 \(D_i\)。饲养员都住在 \(1\) 号山上。
有一天,猫出去玩。第 \(i\) 只猫去 \(H_i\) 号山玩,玩到时刻 \(T_i\) 停止,然后在原地等饲养员来接。饲养员们必须回收所有的猫。每个饲养员沿着路从 \(1\) 号山走到 \(N\) 号山,把各座山上已经在等待的猫全部接走。饲养员在路上行走需要时间,速度为 \(1\) 米每单位时间。饲养员在每座山上接猫的时间可以忽略,可以携带的猫的数量为无穷大。
例如有两座相距为 \(1\) 的山,一只猫在 \(2\) 号山玩,玩到时刻 \(3\) 开始等待。如果饲养员从 \(1\) 号山在时刻 \(2\) 或 \(3\) 出发,那么他可以接到猫,猫的等待时间为 \(0\) 或 \(1\)。而如果他于时刻 \(1\) 出发,那么他将于时刻 \(2\) 经过 \(2\) 号山,不能接到当时仍在玩的猫。
你的任务是规划每个饲养员从 \(1\) 号山出发的时间,使得所有猫等待时间的总和尽量小。饲养员出发的时间可以为负。
\(N, M ≤ 10^5, P ≤ 100, Di ≤ 10^4, 1 ≤ H_i ≤ N, T_i ≤ 10^9\)
- 设 \(sd_i\) 为 \(i\) 号山到 \(1\) 号山的距离。
- 某饲养员出发时间为 \(s\),则他能接到的猫需要满足 \(s + sd_{H_i} ≥ T_i\),等待时间为:
\]
- 那么令 \(a_i = T_i − sd_{H_i}\),问题转化为在数轴上放置 \(P\) 个存档点,最小化每个 \(a_i\) 和右侧最近的存档点距离之和。
- 很明显所有饲养员只会在某个 \(ai\) 时刻出发,则问题转化为离散问题。
- 把 \(a_i\) 从小到大排序。\(dp_{i,j}\) 表示前 \(i\) 个猫,用 \(j\) 个饲养员接,等待时间之和最小值。
- 转移为:(si 为 ai 的前缀和)
\]
- 第二维可滚动,套用斜率优化一般形式,化为:
\]
- 平面上的点为 \(P_k (k, dp_{k,j−1} + s_k )\),斜率为 \(a_i\)
- 横坐标单调递增,斜率单调递增,可直接单调队列维护。时间复杂度 \(O(NP)\)
[一本通]任务安排
有 \(N\) 个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变。机器会把这 \(N\) 个任务分成若干批,每一批包含连续的若干个任务。
从时刻 \(0\) 开始,任务被分批加工,执行第 \(i\) 个任务所需的时间是 \(T_i\)。另外,在每批任务开始前,机器需要 \(S\) 的启动时间,故执行一批任务所需的时间是启动时间 \(S\) 加上每个任务所需时间之和。
一个任务执行后,将在机器中稍作等待,直至该批任务全部执行完毕。也就是说,同一批任务将在同一时刻完成。
每个任务的费用是它的完成时刻乘以一个费用系数 \(C_i\)。请为机器规划一个分组方案,使得总费用最小。
\(n ≤ 300000, 1 ≤ S ≤ 256, |Ti| ≤ 256, 0 ≤ Ci ≤ 256\)
- 费用需要差分计算,将每个任务的费用拆到每组任务的花费时间上
- 设 \(dp_i\) 表示前 \(i\) 个任务做完后,对总费用的贡献最小值。
- 设 \(st\) 为 \(T\) 的前缀和,\(sc\) 为 \(c\) 的前缀和。枚举当前上一批任务的右端点 \(j\),有:
\]
- 按照惯例,整理为:
\]
- 二维平面上的点为 \(P_j(sc_j, dp_j − sc_n × st_j − sc_j × S + sc_j × st_j)\),查询斜率为 \(st_i\)。
- 横坐标依然单调递增,可直接维护下凸壳。但是查询斜率不递增了,不能用单调队列维护。
- 用单调栈维护,查询时在单调栈上二分即可。时间复杂度 \(O(n log n)\)。
NOI2007 货币兑换
有两种货物。每天这两种货物的市场价格都会改变,第 \(k\) 天,单价分别为 \(A_k\) 和 \(B_k\)。
有两种交易方式,一种是买,支付 \(P\) 元,获得数量比例为 \(r_k\) 的 A 货物和 B 货物。
另一种是卖,将当前手里占比为 \(p\) 的 \(A\) 货物和 \(B\) 货物卖成现金。\(p ∈ [0, 1]\)。
每天可以自由买卖,初始没有货物,有 \(S\) 元钱,求 \(N\) 天后最多多少现金。
\(N ≤ 10^5, 0 < Ak , Bk ≤ 10, 0 < rk ≤ 100\)
- 必然存在一种最优的方案满足:每次买都花光所有现金,每次卖都卖光所有货物。
- 那么在同一天内,一定是先卖光(或者不卖),再全买进(或者不买)。
- 设 dpi 表示第 i 天卖光 (或者不卖) 后最多有多少钱。枚举上次是第 j 天买的,得:
\]
- 其中 \(a_j =\frac{r_j}{A_j×r_j+B_j}, b_j = \frac{1}{A_j×r_j+B_j}\) ,表示当天 \(1\) 元钱会买进 \(A\) 货物和 \(B\) 货物的数量。
- 我们姑且忽略和 \(dp_{i−1}\) 取 \(max\) 的那部分,按照惯例定义 \(res_j = dp_j × (a_j × A_i + b_j × B_i)\),推式子可得:
\]
- 此时二维平面上的点为 \(P_j(dp_j\times a_j, dp_j\times b_j)\),用斜率为 \(−\frac{A_i}{B_i}\) 的直线去过这些点,最大化纵截距。
- 无论是点的横坐标还是斜率都不单调了。可以用李超线段树来做,但斜率优化也可以做。
- 这个题就利用分治加斜率优化去做。直接做时间复杂度为 \(O(n log2 n)\)。但是分治本身结构就是归并排序的结构。利用归并排序,可将时间复杂度降为 \(O(n log n)\)
一般形式其他优化
- 回顾形式 \(G(j) = (−H(i)) × R(j) + (res_j − F(i))\)。用斜率为 \(−H(i)\) 的直线过 \(P_j(R(j), G(j)))\)
- 现在我们考虑,如果横坐标 \(R(j)\) 不单调递增,怎么维护凸壳呢?
序列上的斜率优化可考虑分治。
- 对于一个分治区间 \([l, mid]\) 和 \([mid + 1, r]\),我们考虑转移点在 \([l, mid]\) 范围内,对 \(i ∈ [mid + 1, r]\) 的所有 \(dp_i\) 的贡献。这样转移点内部就离线下来了,可以做排序,变成了横坐标单调的情况。对于每个 \(i ∈ [mid + 1, r]\),在固定的凸壳上做二分。
- 先递归到左子区间,把 \([l, mid]\) 的所有 \(dp\) 最终值求出来。然后考虑 \([l, mid]\) 对 \([mid + 1, r]\) 的转移。最后递归到 \([mid + 1, r]\),只需考虑内部转移。
相当于一个分治树上的中序遍历。
2025dsfz集训Day12: 斜率优化DP的更多相关文章
- bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)
题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- [BZOJ3156]防御准备(斜率优化DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- BZOJ 3156: 防御准备 斜率优化DP
3156: 防御准备 Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战 ...
- HDU2829 Lawrence(斜率优化dp)
学了模板题之后上网搜下斜率优化dp的题目,然后就看到这道题,知道是斜率dp之后有思路就可以自己做不出来,要是不事先知道的话那就说不定了. 题意:给你n个数,一开始n个数相邻的数之间是被东西连着的,对于 ...
- HDU3507 Print Article(斜率优化dp)
前几天做多校,知道了这世界上存在dp的优化这样的说法,了解了四边形优化dp,所以今天顺带做一道典型的斜率优化,在百度打斜率优化dp,首先弹出来的就是下面这个网址:http://www.cnblogs. ...
- HDU 3507 Print Article(斜率优化DP)
题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...
- 斜率优化dp(POJ1180 Uva1451)
学这个斜率优化dp却找到这个真心容易出错的题目,其中要从n倒过来到1的确实没有想到,另外斜率优化dp的算法一开始看网上各种大牛博客自以为懂了,最后才发现是错了. 不过觉得看那些博客中都是用文字来描述, ...
随机推荐
- Delphi XE TVirtualQuery raised exception class ESQLiteError with message 'duplicate column name:dw'
使用Delphi XE7+UniDAC+TVirtualQuery开发的过程中,对已经查询到内存中的数据集TUniQuery组件,再次运用SQL语句进行查询 结果程序运行后提示错误:raised ex ...
- 十二. Redis 集群操作配置(超详细配图,配截图详细说明)
十二. Redis 集群操作配置(超详细配图,配截图详细说明) @ 目录 十二. Redis 集群操作配置(超详细配图,配截图详细说明) 1. 为什么需要集群-高可用性 2. 集群概述(及其搭建) 3 ...
- kubernets学习笔记一
了解kubernets Docker作为单一的容器技术工具并不能很好地定义容器的"组织方式"和"管理规范",难以独立地支撑起生产级大规模容器化部署的要求..因此 ...
- Luogu P10838 『FLA - I』庭中有奇树 题解 [ 绿 ] [ 二分 ] [ 双指针 ] [ 树的遍历 ]
庭中有奇树:很多算法揉在一起的好题. 转化题意 因为要封锁 \(m\) 条路径,根据贪心思想,他一定会封锁最短的 \(m\) 条路径.所以我们能走的最短传送路径就是最短的第 \(m+1\) 条路径. ...
- Hetao P2071 打字游戏 题解 [ 绿 ] [ 最小生成树 ] [ 动态规划 ] [ 编辑距离 ]
打字游戏:MST 套 dp 好题. 首先看这个数据范围,\(O(n^4)\) 把每两个字符串之前的编辑距离求一下很显然吧. 然后我们观察一下每一个 node 的性质,发现他要么自己打完,要么从别人那里 ...
- redis - [02] 安装部署
在Windows和Linux操作系统下的安装部署 一.windows版 (1)访问redis下载地址:https://github.com/tporadowski/redis/releases (2) ...
- 使用 SK 进行向量操作
先祝大家 2025 新年好. 在 2024 年落地的 LLM 应用来看,基本上都是结合 RAG 技术来使用的.因为绝大多数人跟公司是没有 fine-turning 的能力的.不管是在难度还是成本的角度 ...
- 【MATLAB习题】铰链四杆机构的运动学分析
铰链四杆机构题目&已知数据 matlab 代码 主程序文件: function main %输入已知数据 clear; i1=101.6; i2=254; i3=177.8; i4=304.8 ...
- Vulnhub-Node
利用信息收集拿到路径得到账户密码,下载备份文件,base64解密后,利用fcrackzip爆破zip压缩包,得到一个文件,查看app.js,发现泄露的账户密码,连接ssh,成功连接,利用ubuntu历 ...
- openpyxl 写入字典
def write(self,data_path, sheetname,value): index = len(value) workbook = openpyxl.Workbook() sheet ...