Skip to content

斜率优化 笔记 ​

推式子比代码长。

1. P3195 [HNOI2008] 玩具装箱 ​

第一步:写出暴力 ​

设 fi 表示前 i 个玩具的最小答案,si 表示 C 的前缀和。

fi=minj=1i−1{fj−1+(i−j+si−sj−1−L)2}

第二步:分流 & 拆式子 ​

令 fi,j=fj−1+(i−j+si−sj−1−L)2。

即当 i 从 j 这个位置转移时的最小答案。

将只和 i 有关的和只和 j 有关的提出来。

令 gi=i+si−L[1],hi=i+si−1。

[1]:常数项放哪边或者哪边都不放均可,由于待会还要拆平方,虽然最后会被消掉,但是哪边都不放中间的式子就会很长。

fi,j=fj−1+(gi−hj)2=fj−1+gi2−2gihj+hj2

第三步:讨论后面的转移点比前面的更优的条件 ​

若 j1<j2,且 j2 比 j1 更优,即 fi,j1>fi,j2:

fj1−1+gi2−2gihj1+hj12>fj2−1+gi2−2gihj2+hj22(fj1−1+hj12)−(fj2−1+hj22)>2gi(hj1−hj2)

令 yi=fi−1+hi2:

yj1−yj2>2gi(hj1−hj2)

s 单调递增,所以 h 也单调递增,所以 hj1−hj2<0:

yj1−yj2hj1−hj2<2gi

左边这个式子就相当于平面内经过 A(hj1,yj2) 和 B(hj2,yj2) 的直线 AB 的斜率(就是一次函数的 k),也就是说当这个斜率小于 2gi 时,j2 更优。

第四步:单调队列维护 ​

令 K(j1,j2)=yj1−yj2hj1−hj2。

可以证明转移点间的斜率一定是单调递增的:

考虑反证法。当 j1<j2<j3,K(j1,j2)>K(j2,j3) 时,假设 j2 是最优转移点。则 j2 优于 j1⇒K(j1,j2)<2gi,j2 也优于 j3⇒K(j2,j3)>2gi,即 K(j1,j2)<2gi<K(j2,j3),与条件矛盾,故假设不成立。

运用单调队列的思想,维护队列中相邻两个点的斜率单调递增,且保证队头和队头后一个点的斜率 >2gi,由于斜率单调递增,故前一个点总是优于后一个点,取队头就是答案。

所有情况的单调队列取法总结:

  • K(j1,j2)<gi,gi 单调增:维护队头斜率大于 gi,斜率单调增,转移取队头。

  • K(j1,j2)<gi,gi 单调减:维护队尾斜率小于 gi,斜率单调增,转移取队尾。

  • K(j1,j2)>gi,gi 单调增:维护队尾斜率大于 gi,斜率单调减,转移取队尾。

  • K(j1,j2)>gi,gi 单调减:维护队头斜率小于 gi,斜率单调减,转移取队头。

先删尾,再加入,再删头,再转移。

2. ​

简要题意:有一个长度为 n≤106 长度的数轴,除 0 号点外每个点上有个分数 ai。任选跳跃策略,从 0 号点跳到 n 号点,从 j 跳到 i 的收益是 ai(i−j),求最大分数。

fi=maxj=0i−1{fj+ai(i−j)}

令 fi,j=fj+iai−jai。

若 j1<j2,且 fj1<fj2:

fj1+iai−j1ai<fj2+iai−j2aifj1−fj2<ai(j1−j2)fj1−fj2j1−j2>ai

其他情况 1:与斜率比较的对象没有单调性 ​

其实很好处理,根据大于号和小于号,单调队列维护递增还是递减的四条规律仍然适用,但是不能再保证队头或队尾和比较对象的关系,所以变成单调栈,然后二分找就行了。

3. P4655 [CEOI2017] Building Bridges ​

wi←wi−1+wifi=minj=1i−1{fj+(hi−hj)2+wi−1−wj}

光速推柿子(因为没啥用),令 Gi=hi2+wi−1,Hi=fj+hj2−wj,得到:

Hj1−Hj2>2Hi(hj1−hj2)

然后发现由于 h 没有单调性,连斜率小于 / 大于一个对象的形式都写不出来。

其他情况 2:斜率也没有单调性 ​

把式子推回去到这:

fi=minj=1i−1{fj+hi2−2hihj+hj2+wi−1−wj}

令 k=−2hj,b=fj+hj2−wj。

fi=hi2+wi−1+minj=1i−1{khi+b}

min 里的可以用 李超线段树 维护。相当于查询 x=hi 时,y 的最小值。由于插入的是直线而不是线段,所有数都是整数没有精度问题,而且只关心最小值的大小而不是编号,所以比模板好写多了。

不过要注意边界问题,第 0 条直线的 b0=∞。

4. P4027 [NOI2007] 货币兑换 ​

贪心,如果在第 j 天买入并在第 i 天卖出,那么肯定是在第 j 天全买第 i 天全卖最优。

设 pi,qi 分别表示第 i 天 a,b 能买多少个:

pi=firiairi+bi,qi=fiairi+bifi=max(fi−1,maxj=1i−1{aipj+biqj})=max(fi−1,maxj=1i−1{bi(pjaibi+qj)})

把右边那一部分看成一次函数,李超线段树维护即可。

其他情况 2.1:x 坐标是小数 ​

离散化即可,小心 unique 后炸精度。

更多类似题目 ​

1/2. P3628 [APIO2010] 特别行动队 / SP15648 APIO10A - Commando ​

3. P5017 [NOIP2018 普及组] 摆渡车 ​

4. P2900 [USACO08MAR] Land Acquisition G ​

最近更新