浅谈带权二分或者斜率凸优化

APOI讲了这个东西,还有THU命题的《九省·林克卡特树》,感受好像很热点的样子。函数

带权二分是一类对DP的优化,对于某些最优化问题的(2d/yd)DP,经过这种优化,其效率能够达到简化后的(1d/yd)DP的效率乘一个log优化

((xd/yd)DP是指状态数为n^x级且每种状态的转移数为$n^y$级的DP,这个形式下的DP的最好效率是$n^{x+y}$的)blog

有这么一个(2d/yd)DP:效率

——对于某状态二元组(i,j),有最优值f[i][j];变量

——每一个f[i][j]的得出,都须要比较$n^y$个其余的状态二元组,从中挑出一个可使f[i][j]更优的状态做为前驱来进行转移;技巧

——须要某一个f[n][m]的结果(由于n和m同级,因此能够认为状态数为$n^2$级)。方法

考虑优化这个(2d/yd)DP,也就是把它降为一个其余的(x'd/y'd)DP使得x'+y'<2+yim

考虑使y减少——总结

因为在此类DP中,每个状态的得出,最终只须要从全部备选的前驱中挑一个来进行转移,数据

因而在最理想的状况(也就是通过各类神奇优化以后),咱们能够不通过比较一步找到每一个状态的前驱

这样就是一个(2d/0d)的DP了,效率$O(n^2)$,

对于决策过程的优化就到此为止了,这一部分并非本文的重点,因此能够看出,他被一笔带过了。

如今咱们考虑优化状态数,也就是把2d变成1d——

考虑有一个(2d/yd)DP,咱们要获得的是状态(n,m)的最值f[n][m]

若是这个DP没有第二位限制的话是一个很是好搞的1dDP(状态为x时,其答案f'[x]为原来f[x][i]中i枚举全部值时的最优值,因为DP状态的精确性有所降低,因此通常状况下f'的DP的确能够是一个(1d/y'd)DP,并且y'<=y,也就是一个比以前更好搞的DP)

那咱们尽可能但愿把第二位消掉,以优化状态数

设有函数F知足F(i)=f[n][i];

F在整点处的最值,也是对于全部i而言f[n][i]的最值;

那么设这个值为f'[n],能够发现f'[n]就是咱们上文中所说的消去第二位限制后出现的那个很好搞的DP

然而,这样获得的f'[n]=f[n][x],却并不能保证x=m。

考虑给F搭配另外一个函数G以获得函数H,使得H(x)=F(x)+G(x)

且H(x)在x=m时取得整点处的最值;

这样的话,设这个最值为h'[n],若是h'[n]也刚好是个很好搞的(1d/y''d)DP(这须要G十分恰当),那么h'[n]就能够是咱们优化状态数的产物。而最终的答案就是h'[n]-G(m)了

 

带权二分(斜率凸优化)就是上述讨论的一个简单易行而应用普遍的特例。

好比有f[a][b]=max(枚举c<b){f[a-1][c]+val[c+1,b]},

咱们试图消去状态表示中的第一位a,他表明转移次数,

由以前的定义有$F_{max}$=f'[b]=max(枚举i){f[i][b]}

能够发现f'[x]是一个很好搞的DP——

f'[b]=max(枚举c<b){f'[c]+val[c+1,b]}

若是F的曲线知足以下图的凸性:

好比F(x)是下图这样的曲线

那么只要H(x)是F(x)搭配不一样斜率的正比例函数G(x)(即H(x)=F(x)+K*x,其中G(x)=K*x),随着K的调动,就可使不一样的x变成H(x)取到最值的地方

并且h'[x]也是一个很好搞的DP——

当G的斜率为K时,h'[b]=max(枚举c){h'[c]+val[c+1,b]+K}

(每转移一次就至关于原来的f中被隐去的维度其数值+1,这意味着G的自变量+1,此时G对h'多贡献了K)

因而剩下的问题就是如何找到一个合适的K,使得H的最优值h'[n]在m处取得了

由于只要K合适,那么答案就是f[n][m]=h'[n]-m*K,而h'是一个很好搞的DP,因而此类题目就结了。

咱们发现因为F函数曲线的凸性,当K逐渐减少时,H的最值取得的位置逐渐右移,

这意味着K能够二分取得:

每次二分一个K’,DP计算当前的h'[n],并计算当前h'[n]=H(x)的这个x是那一个x

若是这个x>m就blabla

若是这个x<m就blabla

这样最后会获得了一个合适的K,并同时也就获得问题的答案了。

而对于F的曲线知足以下图凸性的状况:

 

咱们能够用一样的方法,搭配不一样斜率的正比例函数G(x)使得H(x)的min值在不一样的x处取得。

方法以前的相似。

总结:

对于f[n][m]

若是f[n][m]求解max值

且设F(x)=f[n][x],有F(x)是随x增长,斜率递减的函数

那么咱们能够经过斜率凸优化解决这个问题

若是f[n][m]求解min值

且设F(x)=f[n][x],有F(x)是随x增长,斜率增的函数

那么咱们能够经过斜率凸优化解决这个问题

例子:

有以下DP方程——

$$f_{[i][j]}=MIN_{k∈[0,j-1]}f_{[i-1][k]}+(sum_{l=k+1}^{j}a[l])^2$$

$$且对于全部i>j,有f_{[i][j]}=INF$$

其中a[x]为输入数据

求解$f_{[m][n]}$

 

能够看出$f_{[m][n]}$为把n个数分红m段,求每段和的平方的和。

设$F(x)=f{[x][n]}$能够证实F(x)是一个随x增长,斜率增的函数。

若是没有m段的限制的话

有$f'_{[j]}=MIN_{k∈[0,j-1]}f_{[k]}+(sum_{l=k+1}^{j}a[l])^2$

经过预处理前缀和以及一些斜率优化技巧,这个方程能够作到O(n)

若是咱们给每次划分搭配一个费用K的话

就有$h'_{[j]}=MIN_{k∈[0,j-1]}h_{[k]}+(sum_{l=k+1}^{j}a[l])^2+K$

一样能够斜率优化作到O(n),

这样,咱们二分K,断定此时$h'_{[n]}$对应的划分次数与m的关系,从而找的一个合适的K,进而找的问题的答案。

最终效率为O(nlogV)

相关文章
相关标签/搜索