http://poj.org/problem?id=2018
此乃神题……详见04年集训队论文周源的,看了这个对斜率优化dp的理解也会好些。
分析:
我们要求的是{S[j]-s[i-1]}/{j-(i-1)}最大,可以发现这个形式满足直线斜率式,于是原题就可以看成平面上有一些点P(i,s[i]),然后求这些点中横距大于F的两点的最大斜率。
这么转化后仍然需要n^2的枚举
但当你枚举一个点,并在前面的点中枚举找到一个和它结合斜率最大的解时,可以发现是像凸包那样的维护一个下凹的曲线,因为如果某个点是上凸的,那么易得这个点得到的斜率必定不会比前一个点大!这也就是说我们在从F..n枚举区间的最右端点的时候,可以边维护前面的下凹曲线(代码和凸包非常相似)。那么最后一个问题就是维护了这个下凹曲线,设上面有m个点,我们现在枚举到的最右端点为i点,那么我们怎么从m个点中找出与i点形成的直线斜率最大的点呢?很容易想到二分,但不过有更简单的,因为当我们枚举i点并从m个点中找出点j使得k(i,j)最大,那么对于接下来枚举的(n-i+1)个最右端点而言,如果要形成一个比ans还要大的K(i',j'),那么一定是i'与i相比是上凸的,j'与j相比是凸的或者相同才有可能大于ans。这意味着当我们某次枚举从m个点找出了一个最优的j点,那么在这个下凹集合上j点之前的点就可以Pass掉了。
时间效率:O(nlog2)排序,O(n)扫描