發現本身傻傻分不清斜率優化和決策單調性→_→,被一些博客誤導了。。因而總結一下。萌新們能夠先寫寫[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]}}$$
而後發現這個東西很符合單調隊列的尿性:
問題就這樣優化到了${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]}$取最小值的狀況下的):
不錯,你必定已經發現第一種狀況所對應的維護方式不是跟以前所說「數」的單調隊列維護方式如出一轍嗎,沒錯,其實這只是兩種不一樣的解題方式所得出來的一樣的結果。
兩種方法各有優缺點吧,「形」的角度比較方便理解,對於更高深的cdq分治維護凸包能夠比較清晰的瞭解。可是遇到複雜的dp方程以及決策單調性證實就得靠「數」了(好比國王飲水記),看狀況使用吧。
以前說的決策單調性是斜率優化的基礎這句話其實並不嚴謹,像這種從圖形角度來求解的斜率優化就並無用到決策單調性。想想若是能證實決策單調性,那麼必定就是對${a}$和${b}$的單調性有要求的,不然的話就是什麼斜率不單調啦,在凸包上二分啦什麼的。
這就是斜率優化啦。
回顧以前斜率優化的運用,它必需要有一個前提條件:${b}$(橫座標)單增。而若是${b[j]}$不單調怎麼辦呢?還能不能用斜率優化呢?
答案是能夠的,咱們須要使用CDQ分治或者splay來解決這個問題。
斜率單調暴力移指針
斜率不單調二分找答案
x座標單調開單調隊列
x座標不單調開平衡樹|cdq分治
參考資料:
http://blog.sina.com.cn/s/blog_7a1746820100xztv.html