【学习笔记】Slope Trick

Slope Trick

CF上讲解Slope Trick的博客

Slope Trick 是一种优化 DP 的方法,核心思想是通过存储DP转移的一些关键信息(如分段函数的分段点和最左/右边的一段函数)从而利用数据结构高效维护转移。(不是斜率优化DP

接下来都以凸函数,维护最左边的函数为例

注:图中所画斜率有小于 1 的只是为了好看,实际题目的斜率一定为整数

一般可以使用 Slope Trick 优化的DP方程有以下要求:

  • 是连续的
  • 是分段一次函数
  • 是凸函数(斜率单调不升,图像上凸)或凹函数

分段一次凸函数具有非常优秀的性质:

  • 两个凸函数相加还是凸函数
    设凸函数 F(i)G(i),其分段点集合分别为 LFLG,其最右端的函数分别为 RF(i)RG(i),则 H(i)=F(i)+G(i) 也是凸函数,分段点集合满足 LH=LFLGRH(i)=RF(i)+RG(i)

  • 凸函数加一次函数还是凸函数

这样我们将所有斜率减少(增加)1位置放到数据结构里面维护,也就是说如果一个地方的斜率变化大于 1 就加多次。

如函数

{x+2x<111x<1 2x+3x1

图像为

image

我们维护最左边的图像信息 k=1,b=2 和分段点集合 {1,1,1},其中 x=1 这个位置加了两次

再如绝对值函数(凹函数) |xw|,维护 k=1,b=w 和分段点集合 {w,w}

事实上每一个分段一次凸函数都可以这样表示,我们就可以快速维护许多函数操作。

几种常见的函数操作:

  • 相加
    直接最左边图像 k,b 相加,分段点集合合并。

  • 找最大/小值
    就是斜率为零的那一段,用大根堆 L 维护其左边的所有分段点,R 维护右边的,始终保证 k=L.size(),其余点扔进 L
    堆顶即为最大值的左端点和右端点。

  • 加一次函数
    例如加上一个 y=x,就只用把 R 堆顶的第一个元素扔到 L 里面
    如果加的一次函数斜率较大,为了保证复杂度,修改集合的定义为每个位置的斜率变化量即前/后缀差分,修改 k,b 即可。

  • 前后缀max
    前缀 max 就是直接扔掉 R 里的所有点,后缀就是扔掉 L 里的所有点。

  • 平移
    只用维护 k,b 的变化,分段点打平移标记。

  • 翻转
    只用维护 k,b 的变化,分段点打翻转标记。

答案统计的时候有两种方法,一种是还原图像,另一种是记录决策点(一般是斜率为零的线段端点)

例题:CF713C

给定一个有 n 个正整数的数组,一次操作中,可以把任意一个元素加一或减一。(元素可被减至负数或 0),求使得原序列严格递增的求最小操作次数。

首先把严格递增转化为单调不降,只需令 ai=i,然后就是线性 DP

fi,j=mink=1jf(i1,k)+|aij|

Fi(x)=fi,xGi(x)=mink=1xFi(x),改写成函数的形式,则转移方程就是

Fi(x)=Gi1(x)+|aix|

发现这是个斜率单调不降的凹函数:

首先 F1(x)=|aix| 这是个凹函数,然后 Gi(x) 是个前缀 min

凹函数加凹函数,所以 Fi(x) 也是凹函数。

所以状态转移其实就是维护凹函数相加和取前缀 min 两个操作,这很 Slope Trick,发现 Gi(x) 的图像最后一段一定是平的,所以我们只需要维护斜率小于零的大根堆 L

加入绝对值函数 |aix|,相当于在集合中加入元素 {ai,ai},分类讨论 ai 的位置:

  • aiL.top() 时,加的第二个 ai 实际斜率是 1,取前缀 min 时又删除了,所以此时只用加一个 {ai}
  • ai<L.top() 时,先加入 {ai,ai}L.top() 的斜率从 0 变成 1,取前缀 min 时需要删除,所以 pop 出去。

这样我们同时完成了凹函数相加和取前缀 min 操作。

这道题有个很好的性质就是你每次决策点就是堆顶,所以直接累加答案,这道题就做完了。

四倍经验:CF713CCF13CP2893P4597,注意是严格非降还是严格上升
Code:

priority_queue<int> q;
main(){
int ans=0;
int n;cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
x=x-i;
q.push(x);
if(x<q.top()){
q.push(x);
ans+=q.top()-x;
q.pop();
}
}
cout<<ans<<endl;
}
posted @   CCComfy  阅读(1799)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示