DP优化方法

斜率优化

这个东西并不难

就是求形如 kx±b 的最大值或者最小值,一般来说,设整个柿子为 b ,通过移项来处理就可以了,取 min/max 分别对应下 / 上凸壳,找值相当于求固定斜率对于这个凸壳的切点

现在着重精力来看一下这个斜率的柿子

yiyjxixj<ykyixkxi

对于DP 而言,这里要求加入一些点,同时进行查询,这里分为三种情况来讨论:

  1. 加入的点的横坐标单调,而且直线的斜率单调

如果加入的顺序和直线在凸壳上切点的增长方向相同,就可以直接单调队列来做

  1. 横坐标单调,斜率不单调

这里也不难,只要二分一下单调栈就可以了,上面的方向要是冲突也可以这么做

  1. 横坐标不单调

这就麻烦了

横坐标要是不单调,那就变成了个动态凸壳,主流的有四种做法,这里介绍 CDQ

网上一直没有找到较好的解释博客,这里推荐去这题的题解区

我们发现,如果把整个修改和查询抽象成一个序列,那可以把序列的左半边,的答案先算出来,然后根据答案建出凸壳,然后去更新右半边的答案

这就是 CDQ 的基本流程了,不难写,复杂度两只 log

同时,李超线段树虽然不太可以维护凸包,但只要进行一点变化,就可以来维护这类斜率优化问题,复杂度和CDQ 一样,可以参考这个

决策单调性

这里分为几种:

  1. 1D 单调性

形如 fi=min/max{f[j1]}+val(i,j)

这种东西要是有单调性,那也没有我已知的方法做到线性,就能二分枚举中间点的决策点来处理

当然,二分队列也是可以的,接下来介绍一下这种方法

在队列中,维护一个三元组 [s,l,r] ,代表扫到当前,这个状态在区间 [l,r] 是最佳的方案,在队列里,元素按照决策顺序从小到大排列

假设当前已经到了位置 i

将队头的超时的决策去掉

来到队尾,先更新队尾节点的左端点,然后比较一下,如果这个点在其所有的决策空间内都被这个点吊打,那就把这个点给去掉

然后,二分出队尾元素与当前元素的决策交界点,将当前元素压入

一般来说,最好先清空无用决策,再进行二分,不然容易让自己的二分假掉,不过好像也没影响

假如价值的计算是一个初等函数,可以借助一些数学方法做到线性

  1. 2D 非区间 DP

形如 fi,j=min/max{fi1,k1}+val(i,k)

这个就是标准的四边形不等式理论了,对于这个转移,自然是有单调性的,具体来说 Mi,j[Mi1,j,Mi,j+1]

细节来说,枚举第二维的时候,需要倒序来做

  1. 2D 区间 DP

这个就是四边形不等式了,直接看 OI-Wiki 就可以了

posted @   颈流推进  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示