斜率優化學習筆記

發現本身傻傻分不清斜率優化和決策單調性→_→,被一些博客誤導了。。因而總結一下。萌新們能夠先寫寫[hnoi2008]玩具裝箱,並不難。html


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

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

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

  按照一向的套路,先數學概括法證實決策單調性。spa

  1.概括假設:.net

    假設有${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】}$$htm

  2.概括推理:blog

    此時後面有狀態${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

相關文章
相關標籤/搜索