動態規劃專題(五) 斜率優化DP

2022-05-14 14:30:09 字數 1738 閱讀 1796

斜率優化\(dp\)是難倒我很久的乙個演算法,我花了很長時間都難以理解。後來,經過無數次的研究加以對一些例題的理解,總算啃下了這根硬骨頭。

斜率優化\(dp\)的式子略有些複雜,大致可以表示成這樣:

\[f_i=min_^(a(j)-b(j)*s(i)+c(i))

\]其中\(a(j)\)和\(b(j)\)是兩個只與\(j\)有關的函式,\(s(i)\)和\(c(i)\)是兩個只與\(i\)有關的函式,式子中的\(min\)其實也可以替換成\(max\),但這裡以\(min\)為例。

不難發現,如果只有\(a(j)\)和\(c(i)\)兩項,就是單調佇列優化\(dp\)

的基本式子了。

但是,由於式子中含有\(b(j)*s(i)\)這一項既與\(i\)相關,又與\(j\)相關的式子,就不能直接用單調佇列,而要進行一定轉化了。

考慮將\(a(j)\)移到等號左邊,並將\(f_i\)移到等號右邊,則原式可以轉化成這樣:

\[a(j)=b(j)*s(i)+(f_i-c(i))

\]注意,在\(i\)不變的時候,我們可以將只與\(i\)有關的項看成常數項。

於是,這個函式就可以看作一條直線,其中\(s(i)\)就相當於這條直線的斜率,而\(f_i-c(i)\)就相當於這條直線的截距

而\(c(i)\)是固定的,因此,如果要讓\(f_i\)最小,則應讓\(f_i-c(i)\)最小,對應到影象中就是讓截距最小。

那麼應如何讓截距最小呢?

首先,我們可以想象有一條斜率固定的直線(我太懶,不想畫圖... ...),然後圖上有若干個點,現在要用這條直線從圖的最下方往上慢慢移動,直至碰到第乙個點,而這個點就是我們要找的最優點。

則不難發現,如果連續的三個點呈上凸狀,則無論該直線斜率取多少,碰到的第乙個點都不可能是中間這個點。

換句話說,就是中間這個點對答案沒有任何貢獻了。

於是就有乙個策略:當我們要加入乙個新的點時,比較當前點與前乙個插入的點\(s_1\)、前乙個插入的點與倒數第二個插入的點的斜率\(s_2\),如果\(s_1\le s_2\),則可將前乙個插入的點彈出。

重複此操作,直至\(s_1>s_2\)或圖上只剩乙個點,然後將當前點插入。

但是,這樣一來,我們好像還是沒能求出最優解。

此時又有兩種操作方式:在凸包上二分單調佇列維護最優解

對於某些問題,它可以確保決策單調性,即乙個點如果當前不是最優解,則以後都不可能是最優解了。這樣的問題可以直接用單調佇列來維護最優解。

但有些問題卻不一定滿足這種性質,此時就需要在凸包上二分最優解了,但依然需要用單調佇列來維護點集。

所以,如果你不會單調佇列,最好趕緊去研究一下,然後再學習斜率優化\(dp\)。

第一道例題:【bzoj2726】[sdoi2012] 任務安排

聽說是入門題?洛谷上的弱化版可以直接單調佇列維護,但是\(bzoj\)上存在負數,需要在凸包上二分。

第二道例題:【cf311b】cats transport

一眼看上去像是\(wqs\)二分,其實題意轉換後可以直接斜率優化。

第三道例題:【洛谷3648】[apio2014] 序列分割

一開始覺得是區間\(dp\),結果一看資料範圍,推了波性質,才發現其實可以用斜率優化\(dp\)來做。

動態規劃 單調斜率優化DP

acwing 1087.修剪草坪 旅行商問題 輸入樣例 641 351 23 輸出樣例 acwing 1087.修剪草坪 動態規劃 f i max f i 1 f i j 1 sum i j sum i f i 表示從前i個中選,且合法的方案數。令x i j,則有 f i min f i 1 f x...

動態規劃 斜率優化

一 引用 一般dp 方程可以轉化成 dp i f j x i 的形式,其中 f j 中儲存了只與 j相關的量。這樣的 dp方程可以用單調佇列進行優化,從而使得 o n 2 的複雜度降到 o n 可是並不是所有的方程都可以轉化成上面的形式,舉個例子 dp i dp j x i x j x i x j ...

斜率優化動態規劃

fi min fj s i2 sj l 2 2 si s j l fi min f j s i2 sj l 2 2si sj l 形如這個式子關於i的項與關於j的項混雜 相乘 的狀態轉移方程,可以使用斜率優化來加速 接下來以優化這個式子為例說說斜率優化.將上方給出的式子去掉 min min,僅關於j...