斜率優化學習筆記


發現自己傻傻分不清斜率優化和決策單調性→_→,被一些博客誤導了。。於是總結一下。萌新們可以先寫寫[hnoi2008]玩具裝箱,並不難。


  相信有心想學習斜率優化的同志們一定自己摸索着寫過[hnoi2008]玩具裝箱這道題吧,我剛開始學習斜率優化的時候,也是寫了這個,然后似懂非懂的發現,好像斜率優化就是先證明決策單調性,然后再用單調隊列維護一下什么的,這不就是套個模板的東西嗎→_→。

  對於某一類型的dp方程$${f[i]=Min(a[i]*b[j]+c[j]+d[i])}$$

  其中$a[x],b[x],c[x],d[x]$是關於$x$的函數,且$b$單增。$——————【1】$

  按照一貫的套路,先數學歸納法證明決策單調性。

  1.歸納假設:

    假設有${i}$前兩個決策點${j,k(j<k)}$,且${k}$的決策要比${j}$好,即:

$${a[i]*b[j]+c[j]+d[i]>=a[i]*b[k]+c[k]+d[i],j<k——————【2】}$$

  2.歸納推理:

    此時后面有狀態${i+1}$,這里我們為了簡單起見,不妨設${a[i+1]=a[i]-v,v>0}$,也就是${a}$單調遞減。$${即證:a[i+1]*b[j]+c[j]+d[i+1] >= a[i+1]*b[k]+c[k]+d[i+1]}$$

$${(a[i]-v)*b[j]+c[j]+d[i+1] >= (a[i]-v)*b[k]+c[k]+d[i+1]}$$

$${化簡得:a[i]*b[j]+v*b[k]+c[j] >= a[i]*b[k]+v*b[j]+c[k]}$$

$${~}$$

$${由【2】得:a[i]*b[j]+c[j] >= a[i]*b[k]+c[k]}$$

$${由【1】得:b[k]>b[j]}$$

$${又\because v>0}$$

$${\therefore v*b[k] >= v*b[j]}$$

$${得證}$$

  所以,決策單調性是存在的。我們將由決策單調性得出的式子展開,化成斜率式:

$${a[i]*b[j]+c[j]+d[i]>=a[i]*b[k]+c[k]+d[i],j<k}$$

$${-a[i]>=\frac{c[k]-c[j]}{b[k]-b[j]}}$$

  記斜率$${slope(i,j)=\frac{c[k]-c[j]}{b[k]-b[j]}}$$

  然后發現這個東西很符合單調隊列的尿性:

  1. ${-a[i]>=slope(q[l],q[l+1])}$。因為${q[l]}$在${q[l+1]}$之前加入,那么顯然這個式子就表示${q[l]}$決策不如${q[l+1]}$優,我們可以將隊首pop掉。
  2. ${slope(q[r-1],q[r])>slope(q[r],i)}$。假設我們在后面存在一個${a[t]}$使得${-a[t]>=slope(q[r-1],q[r])}$那么等到pop了${q[r-1]}$之后,${-a[t]}$一定也會${>=slope(q[r],i)}$,${q[r]}$也會被pop。所以說${q[r]}$實際上是無用的,我們可以直接將它pop掉。

  問題就這樣優化到了${O(n)}$。

  回顧一下我們之所以可以使用斜率優化,是因為這個dp方程具有決策單調性;否則我們推不出斜率式。之后我們將決策單調性的式子變形為斜率式,當滿足斜率式的時候就表明前一個決策不如后一個決策優,一切都是圍繞着決策單調性開展的,可以說決策單調性是斜率優化的前提。(那是真的么,欲知后事,請看下文)

  現在我們換一個角度來考慮問題,剛剛是直接從”數“的角度進行了嚴謹的證明,那么我們現在從”形“的角度來意會。


  dp方程:$${f[i]=Min(a[i]*b[j]+c[j]+d[i]),b[j]單增}$$

  我們這里沿用上面“數”的條件:${a}$單減,${b}$單增。

  移項:$${-a[i]*b[j]+f[i]=c[j]+d[i]}$$

  是不是很像直線的斜截式:${-a[i]}$為直線的斜率;直線過點:${(b[j],c[j]+d[i])}$;${f[i]}$即為直線在Y軸上的截距。

  

  可以看出,因為${f[i]}$要盡可能小,所以我們把之前小於${i}$的${j}$畫在平面直角坐標系上,一如線性規划,把這條斜線自下往上平移時遇到的第一個點,即能使目前狀態有最小值的點。於是我們需要維護一個下凸殼,把那些肯定不會貢獻的點刪掉。

  我們用一個單調隊列維護這個凸殼,因為要保證凸殼的下凸性,所以我們顯然可以得到單調隊列pop隊尾的條件:${slope(q[r-1],q[r])>slope(q[r],i)}$。

  考慮什么情況下pop隊首元素(這里我們的討論都是基於${f[i]}$取最小值的情況下的):

  1. 斜率${-a[i]}$單增(因為${a}$單減)。${-a[i]>slope(q[l],q[l+1])}$。
  2. 斜率不單調。無法pop隊首,二分或者三分查找隊列中的最優解。二分做法:假設你要在上凸包上二分找斜率為${k}$的切線。取中間的${mid}$號點,如果${mid+1}$存在且與${mid}$點的斜率小於${k}$,則${l=mid+1}$;如果${mid-1}$存在且與${mid}$點的斜率大於${k}$,則${r=mid-1}$;如果上面兩條都不滿足,則${mid}$就是切點。

  不錯,你一定已經發現第一種情況所對應的維護方式不是跟之前所說“數”的單調隊列維護方式一模一樣嗎,沒錯,其實這只是兩種不同的解題方式所得出來的同樣的結果

  兩種方法各有優缺點吧,“形”的角度比較方便理解,對於更高深的cdq分治維護凸包可以比較清晰的了解。但是遇到復雜的dp方程以及決策單調性證明就得靠“數”了(比如國王飲水記),看情況使用吧。

  之前說的決策單調性是斜率優化的基礎這句話其實並不嚴謹,像這種從圖形角度來求解的斜率優化就並沒有用到決策單調性。想一想如果能證明決策單調性,那么一定就是對${a}$和${b}$的單調性有要求的,否則的話就是什么斜率不單調啦,在凸包上二分啦什么的。

  這就是斜率優化啦。


小科普

  回顧之前斜率優化的運用,它必須要有一個前提條件:${b}$(橫坐標)單增。而如果${b[j]}$不單調怎么辦呢?還能不能用斜率優化呢?

  答案是可以的,我們需要使用CDQ分治或者splay來解決這個問題。


總結

  斜率單調暴力移指針
  斜率不單調二分找答案
  x坐標單調開單調隊列
  x坐標不單調開平衡樹|cdq分治


參考資料:

http://blog.sina.com.cn/s/blog_7a1746820100xztv.html

http://tieba.baidu.com/p/3671167462

http://blog.csdn.net/u010336344/article/details/52693858

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM