單調佇列優化

2021-08-13 18:04:18 字數 2208 閱讀 9264

單調佇列是一種嚴格單調的佇列,可以單調遞增,也可以單調遞減。隊首位置儲存的是最優解,第二個位置儲存的是次優解。

單調佇列可以有兩個操作:

1、插入乙個新的元素,該元素從隊尾開始向隊首進行搜尋,找到合適的位置插入之,如果該位置原本有元素,則替換它。

2、在過程中從隊首刪除不符合當前要求的元素。

單調佇列實現起來可簡單,可複雜。簡單的乙個陣列,乙個head,乙個tail指標就搞定。複雜的用雙向鍊錶實現。

1、儲存最優解,次優解,ect。

2、利用單調佇列對dp方程進行優化,可將o(n)複雜度降至o(1)。也就是說,將原本會超時的n維dp降優化至n-1維,以求通過。這也是我想記錄的重點

是不是任何dp都可以利用單調佇列進行優化呢?答案是否定的。

記住!只有形如

dp[i]=(max/min)(f[k])+g[i]  (k才能用到單調佇列進行優化。 

優化的物件就是f[k]。

輸入乙個長度為n的整數序列,其中有正有負,陣列中乙個或連續的多個整數組成乙個子陣列,求所有子陣列的和的最大值,要求時間複雜度為o(n)。

轉移方程:dp[i]=max(dp[i-1]+data[i],data[i]);

舉例

輸入:

最大子陣列為:=18;

步驟操作

累加的子陣列和

最大的子陣列和1加1

112加-2-11

3拋棄前面的和-1,加333

4加10

1313

5加-4913

6加716167加2

1818

8加-5

1318

int findgreatestsumofsubarray(int *pdata, int nlength)

g_invalidinput = false;

int ncursum = 0;

int ngreatestsum = 0x80000000;//負無窮

for(int i = 0; i < nlength; ++i)

return ngreatestsum;

}

就是這樣一種方式使得我們原本需要o(n^2^)直接降低成為了線性o(n)。

將物品的數量拆成0、1、2、4……等二的指數,分別計算其價值,當做單獨的物品。因為用這些數可以組合出各種<=m(m為此種物品的數量)的數,也就可以用普通的01揹包

狀態轉移方程

dp[i][j] = max 

時間複雜度為ο(nwlog(m))(n為物品種數,w為揹包大小,m為此物品數量),是一種比較高效的方法。

==優化之後==

時間複雜度為ο(n*w),只是常數可能會稍大。字母含義與上方相同

根據上面的式子,每個j值對應的k有m[i] + 1個裡面去找最大的那個,就相當於在乙個區間裡面找乙個最大值,可以考慮用單調佇列來做這個事情,每次維護佇列是單調遞減的,每次取出來佇列頭作為轉移,每次加入的時候,把前面的比它小的就出隊,然後超過m[i]+1的也出隊。

根據上面的式子,發現對於j這個維數來說,如果兩個體積值對於we[i]取餘的值不一樣,是不可能轉移的。這樣的話直接按照mod的這個值來做轉移,因為mod的值是在[0,we[i]-1],後面再列舉k的值。

假設mod = j % we[i],a = j / we[i],那麼j = a * we[i] + mod,可得:

dp[i][j] = max      

化簡一下,把a - k 用k來替換就可以得到:

dp[i][j] = max + a * va[i]    

這樣掃瞄的時候就是,第一重迴圈是列舉i為n(物品種數),第二重迴圈是列舉的mod從0到we[i]-1,然後第三重迴圈是列舉的餘數為mod的情況下的k值,k值是從0到mod + k * we[i] <= v的對於每乙個k對應乙個這麼大小的揹包,然後找以這個為單調佇列末尾的那個佇列頭的值,完成轉移方程。

單調佇列 優化DP

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

單調佇列優化dp

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

單調佇列優化專題

poj1821 這題是一道比較典型的佇列優化問題吧,狀態方程如下 dp i j max max,dp i 1 j dp i j 1 第i個人不刷,第i個人刷 第j面牆不刷,列舉所有可能結尾的牆 dp i j 表示前i個人刷前j面牆的最大值,且第j面牆必須刷。這題第一用到了雙端佇列deque,學習了不...