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)