單調佇列優化DP問題總結

2022-09-23 21:30:22 字數 1244 閱讀 1860

小結:可見合理的使用哨兵可以簡化對邊界條件的處理

在單調佇列中使用哨兵,主要是在第1個列舉到的數,它依賴的滑動視窗此時為空,無法獲取到head,那麼此時的處理邏輯是什麼樣呢?

一般來講從兩個方面來考慮:

(1) 是不是視窗長度越界,需要出隊首元素?

while (hh <= tt && q[hh] < i - m) hh++;

這種情況下,由於是第1個列舉到的數,肯定不可能視窗長度越界,如果按上面的寫法,hh=0 tt=-1,此時hh>tt,所以while不執行,直接短路運算,沒機會討論q[hh]是否小於i-m,這裡是安全的。

但有的寫法,這裡是這樣的

if(q[hh]< i-m) h++;

此時,沒有了hh<=tt的保護,這裡佇列中還沒有元素,但是卻訪問q[hh]是否小於i-m,這就是在物理意義上有問題了!

(2) 使用佇列頭

res = max(res, s[i] - s[q[hh]]);

此時如果沒有哨兵,同樣存在著無法直接訪問使用q[hh]的問題,造成**邏輯上出錯。

在使用哨兵前,我們要思考真的要虛擬出乙個哨兵,它要解決什麼問題?

(1)佇列天生不是空的,隨時可以取佇列頭

(2)第1個數字的運算邏輯和其它數字沒有區別,不用特殊判斷

總結:(1)增加哨兵能簡單的解決邊界問題

(2)依賴於前序關係的需要加哨兵,不依賴前序關係的可以加哨兵,也可以不加哨兵

(3)如果想要加哨兵,需要遵照下面的原則

i 如果是逆時針,正序遍歷,那麼新增的哨兵應該是第0個,q[++tt]=0

ii 如果是順時針,倒序遍歷,那麼新增的哨兵應該是第n+1個,q[++tt]=n+1

acwing 154. 滑動視窗

int hh = 0, tt = -1;

q[++tt]=0;

for (int i = 1; i <= n; i++)

acwing 135. 最大子序和

int hh = 0, tt = -1;

q[++tt] = 0; //放入哨兵結點

int res = -inf; //預求最大,先設最小

for (int i = 1; i <= n; i++)

acwing 1087. 修剪草坪

int hh = 0, tt = -1;

q[++tt] = 0;

for (int i = 1; i <= n; i++)

單調佇列優化DP 旅行問題

john 打算駕駛一輛汽車周遊乙個環形公路。公路上總共有 n 個車站,每站都有若干公升汽油 有的站可能油量為零 每公升油可以讓汽車行駛一千公尺。john 必須從某個車站出發,一直按順時針 或逆時針 方向走遍所有的車站,並回到起點。在一開始的時候,汽車內油量為零,john 每到乙個車站就把該站所有的油...

單調佇列 優化DP

佇列元素保持單調遞增 減 而保持的方式就是通過插隊,把隊尾破壞了單調性的數全部擠掉,從而使佇列元素保持單調。單調佇列的作用 優化dp。許多單調佇列優化的dp可以使複雜度直接降維,下面就以最簡單的一道題為例 在某兩座城市之間有 n 個烽火台,每個烽火台發出訊號都有一定代價。為了使情報準確地傳遞,在連續...

單調佇列優化dp

形如f i max wi的問題都可以用單調佇列優化。例題 板題 注意乙個地方 求完所有的f後 ans不是f n 而是後面的一段字尾的f 注意字尾的左端點。很顯然是rmq問題 計算字首和sum i 對於固定的右端點 i,我們想讓答案最大等價於max,可以用個單調佇列維護。但是隨便乙個資料結構直接on ...