斜率优化
说明(本文中所有的单调递增递减都不是绝对的,根据实际情况灵活使用)
对于形如(f[i]=max){(f[j]+a[i]+b[i]*c[j])}的状态转移方程,若(b[i])是单调递增的(可以是递减,但维护方式就不同了,下面不再说明),那么我们可以对决策进行斜率优化。
证明
显然,对于两个决策(j和k(j<k)),决策(k)要优于决策(j)当且仅当
[f[j]+a[i]+b[i]*c[j]leq f[k]+a[i]+b[i]*c[k]
]
移项后
[b[i]*(c[j]-c[k]) leq f[k]-f[j]
]
除过去
[-b[i] leq frac{f[k]-f[j]}{c[k]-c[j]}
]
所以若(-b[i] leq frac{f[k]-f[j]}{c[k]-c[j]}),那么本次决策中决策(k)优于决策(j)
(之后所说的斜率均为(frac{f[k]-f[j]}{c[k]-c[j]}))((k>j))
维护
删除
对于这个我们可以用一个单调队列来维护一个单调递减的斜率。
因为(b[i])是单调递增的,所以若决策(k)在一次决策中要优于决策(j),那么之后的所有决策中决策(k)都是要优于决策(j)的,这时我们就可以把决策(j)丢出单调队列
插入
插入一个决策时,由于我们要让斜率满足单调递减,所以若之前的斜率要小于现在的斜率,那么当前面那个斜率被删除后,这个斜率也一定会被删除,也就是说之前队尾的就决策没有用了,直接删除就好(若不删除,可能出现三个决策(a,b,c,决策a优于决策)b(但决策c优于决策a,但是由于决策b的阻隔,妨碍了决策c的使用))。
这样一来,我们每次只需选择队首的决策即可。
然后每个决策最多被插入和删除一次,所以时间复杂度是线性的,一般都能将(O(n^2)的转移优化成O(n))
斜率优化的方法大概就是这样,还是需要灵活运用。