【DP】决策单调性小记
何谓决策单调性?
指的就是在最优化 dp 中,状态的最优转移点单调不减的性质。
这使得我们在做 dp 的时候可以减少冗余计算以达到优化的效果。这类优化方法常用于分段问题。
0x01:四边形不等式
设 表示将前 个位置分段的最小代价, 表示从 转移到 的代价。
若对于 ,满足
我们就说 满足四边形不等式。
结论:若 满足四边形不等式,则该 dp 问题具有决策单调性。
采取反证法:设 的最优决策点为 ,且代价函数 满足四边形不等式。假设对于 ,有 ,则根据最优性质,有
又根据四边形不等式,因为 ,所以有
两式相加,两边消去相同项,得到
也就是说,从 转移到 ,比从 转移更优,与我们的假设相悖,故结论得证。
不过在实战中,四边形不等式一般较难证明,暴力输出各决策点的方式确定决策单调性是最方便的。
0x02:在 dp 中的运用
这一类型的 dp 有分 段问题和区间 dp,朴素的 dp 一般是 的,如果 满足四边形不等式,则我们可以用决策单调性来优化到 的复杂度。
结论:设 表示 的最优决策点,若 满足四边形不等式,则有 。证明略。
例题 1:
题目大意:一条数轴上有 个村庄,第 个村庄的位置为 ,你需要放置 个邮局,使得每个村庄到最近的邮局的距离和最小(,,)。也就是说这个问题是一个分 段问题。
设 表示在前 个村庄中放 个邮局的最小距离和, 表示在编号(从小到大)为 的村庄中放一个邮局的代价(显然放在中位数处最优)。有状态转移方程
先做一遍 的暴力,求出每个状态的最优决策点并输出,我们可以发现满足
于是我们枚举 的决策点时候,可以枚举 ,复杂度降为 。
由于需要用到 的决策点,我们需要倒序枚举 。
例题 2:
题目大意:将一个长度为 的序列分为 段,使得总价值最大。一段区间的价值表示为区间内不同数字的个数。()
还是熟悉的分 段问题, 表示前 个位置分 段,状态转移方程直接出来
我们发现 是个数颜色问题,具有决策单调性(大概就是区间越长越亏),但并不能快速的得出。
注意到每次转移都是由第 层转移到第 层,也就是说同层之间不会转移,我们可以用上一层区间 的结果去转移当前区间 的结果,连续做 次,不就得到答案了吗?
考虑一种分治做法,记 表示从上一次分治的 转移到 。对于 ,我们可以先求出它的最优决策点 ,由决策单调性可知, 一定由 转移而来, 一定由 转移而来。
对于 的计算,由数颜色我们想到类似莫队的方法转移,维护当前左右端点 ,随着分治移动,时间复杂度 , 次分治就是 。
也就是说,当 的贡献难算时,可采用分治的方法。
但注意,分治方法仅适用于一轮决策用上一轮结果转移的情况,如果同层转移则不可用。
习题:
CF868F Yet Another Minimization Problem
0x03: 在 dp 中的运用
状态转移方程一般形如 ,也就是一个分段问题(不过段数不限),这类问题就不能使用分治(因为是同层转移),而是使用二分队列/二分栈维护决策点。
例题:
设 表示前 句诗加上 个空格的长度,则 表示将从 到 的诗句单独分成一行的代价。
通过暴力发现 满足四边形不等式,考虑决策单调性优化。
我们维护最优决策点 ,由于满足决策单调性,对于两个决策点 ,我们一定能找到个分界点 ,使得在 之前()用 转移优于 ,在 之后()用 转移优于 。
于是我们可以维护一个三元组 ,表示在区间 中用 转移较优。根据优劣,对决策点维护个单调队列。
具体地,假设当前在位置 ,我们取队头为最优转移,则队头 出队的前提是 。对于队尾的三元组 ,我们能踢掉他的前提是 和 的分界点 。插入 即插入 。
事实上也不用那么麻烦地维护个三元组,记录队列中相邻两点的分界点即可。
0x04: 斜率优化
若转移方程能简化成 ,由于其中有一项与 都相关,那么就不适用于上面的优化方法。
先不考虑 ,把相关的项放在一起得 。令 ,则整个方程可转化成 的形式(具体来说是把已知的 作为 ,找到决策点 就是找到点 ,所以 只和 有关),其中 和 都是已知的,且 。
那么我们只需用给定的斜率 找到一个点 ,使得经过此点的直线截距取到 即可。
例题:
容易写出转移方程(有做特殊处理):
转换成斜率优化的形式变成
也就是说对于给定的 找到点 满足要求即可。
斜率优化的关键就在此,如何快速地找到这个点呢?显然,我们将这条直线从很低的地方向上平移,碰到的第一个点即为最优,这些决策点即为下凸包上的点(如果要 则反之从上往下,决策点为上凸包)。
设最优决策点为 , 则对于给定的 显然有 (不然就碰不到),而且每次查询的斜率 单调,那么我们可以对此用单调队列维护个下凸包,按照 淘汰头节点即可。
对于 不单调但是插入的点横坐标有序的情况,则用单调栈维护凸包,然后按照 二分即可。
对于 和横坐标都不单调的情况,可用动态凸包/李超树/CDQ 等解决。
2022.10.8 补充:对于维护的是上凸包,且 单增,应该用单调栈维护决策点,如 P5504 [JSOI2011] 柠檬。反之下凸包且 单减同理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】