什么是斜率优化?什么时候用?
首先,我们要知道的一个知识是单调队列(虽然不一定能用,但基本上一定要用)
单调队列是维护一段有序子序列而存在的。
想象一下,一些参差不齐的积木们,如何从一个积木找到其左边的第一个比他大的积木?
一种方案是线段树维护区间信息,单log
另一种是单调栈。
如果说一个积木在另一个积木右边并且比他更大一些,那是不是意味着没有“另一个”积木没有用了,应该扔掉?
那么留下来的积木是什么样的?
有序的,从大到小的。
好了,基本思想介绍到这,不会单调队列的自行学习。
一、什么样的可以用斜率优化
形如 d p [ i ] = X j ∗ ( − k i ) + Y j dp[i]=X_j*(-k_i)+Y_j dp[i]=Xj∗(−ki)+Yj的式子可以通过斜率优化解决。
其中,
X
j
,
Y
j
X_j,Y_j
Xj,Yj均只与
j
j
j有关,
k
i
k_i
ki只与
i
i
i有关。
可以看到,与y轴交点的纵坐标与
d
p
[
i
]
dp[i]
dp[i]的大小相等(此处钦定了
k
[
i
]
k[i]
k[i]>0)
二、如何得到凸壳?
得到如上知识后,要判断的内容:
- dp[i]保大保小?
- k是正是负?
之后可以得到要维护凸壳的信息:上凸壳(越大越好)还是下凸壳(越小越好)
上下凸壳:六边形的上下两半一部分斜率递减一部分斜率递增
得到了斜率递增/递减的信息后,我们可以着手建立凸壳了
对横坐标排序后顺序加入,本质就是单调队列优化,看着斜率单调性加就行!
三、得到凸壳之后,要做什么?
自己切一下,如上的上凸壳,令 一条线最好的切法是与y轴的交点最靠上。
仔细观察k1,k2与上凸壳最好交点的位置,他们有什么特点?
特点:左侧斜率大于你,右侧斜率小于你
如上操作可以通过代数方法得出,读者可以自行操作,这里只介绍较为易于感性理解的图像法
当k递增时,我们会发现,最优交点具有单调性从右向左,反之则从左往右。
如果k不递增会怎么样?
不会怎么样,预处理斜率后二分即可。