單調佇列詳解

2021-08-20 16:24:05 字數 2885 閱讀 8438

剛學單調佇列時,在網上各大部落格找文章學,說實話,寫得很雜,表示自己懵逼了些許,最後硬是啃出來了,所以我決定要寫一篇能讓大部分人都看懂的部落格來。

說單調佇列,那我們就先說說這個單調佇列是個什麼物種。單調佇列從字面上看,無非就是

有某種單調性

的佇列,沒錯,這就是所謂的單調佇列。

單調佇列

它分兩種,

一種是單調遞增的,另外一種是單調遞減的。

不斷地向快取陣列裡讀入元素,也不時地去掉最老的元素,不定期的詢問當前快取陣列裡的最小的元素。

用單調佇列來解決問題,一般都是

需要得到當前的某個範圍內的最小值或最大值。

舉個例子:有  7 6 8 12 9 10 3 七個數字,現在讓你找出範圍( i-4,i ) 的最小值。

那我們就可以這樣模擬一遍。

先初始化 (表示i=0時的值)

i=1 ->

(表示i=1,時,在其範圍內最小的值為0)

-> 7進隊

i=2->

(表示i=2,時,在其範圍內最小的值為7)

->

6比7小,7出,6進

i=3-> 

(表示i=3,時,在其範圍內最小的值為6)

->8比6大,8進  

i=4->

(表示i=4,時,在其範圍內最小的值為6)

->

12比8大,12進

;

i=5-> 

(表示i=4,時,在其範圍內最小的值為6)

-> 9比12小,12out,9比8大,9進

i=6->

但是 單調佇列中元素6的下標是2,不在(2, 6],中,

故6 out,這就是單調佇列的精髓了。故單調隊列為

(表示i=5,時,在其範圍內最小的值為8)

->10比9大,10進 最終 單調隊列為

;

i=7->

(表示i=6,時,在其範圍內最小的值為8)

-> 

3比單調隊列為 的任意值都小,故全out,最終集合為

相信大家看完這個例子了解得有些吧,再次重申一遍,單調佇列的

核心(我認為的哈):

得到當前的某個範圍內的最小值或最大值。

要不是這樣的話,那還有必要這麼麻煩找嗎,直接找前面最小的就好了,可事實不是這樣,題目是有限制的,規定在某個範圍內找。

那我們就來看到例題,加深理解:

description

乙個長度為n的整數序列,從中找出一段不超過m的連續子串行,使得整個序列的和最大。

例如:  1, -3, 5, 1, -2, 3

當m=4時,sum =  5+1-2+3 = 7

當m=2或m=3時,sum = 5+1 = 6

input

多測試用例,每個測試用例:

第一行是兩個正數n, m  ( n, m ≤ 300000 )

第二行是n個整數

output

每個測試用例輸出一行:乙個正整數,表示這n個數的最大子序和長度

sample input

6 41 -3 5 1 -2 3

sample output 7

這題可以用dp來解,在這我們就用單調佇列來解。

我們先把序列的

前i項和加起來

並存到乙個陣列sum[ ]上,那麼

任意連續的子串行和

就為sum [ i ] - sum[ j ]

(i>j &&  j>i-m

)。

那麼我們就可以跟上述例子一樣,一直更新就好了,每次

找出在(i-m,i)範圍內的

最小sum[j]值。

**一:

#include#include///單調佇列,

#include#includeusing namespace std;

typedef long long ll;

const int maxn=300010;

ll sum[maxn];

list que;

int main()

///初始化

ll maxs=sum[1];

que.push_front(1);

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

///初始化

int left=1,right=1;

index1[1]=1;

ll tmax=sum[1];

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

{while(index1[left]=left&&sum[i]

我的標籤:做個有情懷的程式設計師!

單調佇列詳解

剛學單調佇列時,在網上各大部落格找文章學,說實話,寫得很雜,表示自己懵逼了些許,最後硬是啃出來了,所以我決定要寫一篇能讓大部分人都看懂的部落格來。說單調佇列,那我們就先說說這個單調佇列是個什麼物種。單調佇列從字面上看,無非就是有某種單調性的佇列,沒錯,這就是所謂的單調佇列。單調佇列它分兩種,一種是單...

單調棧 單調佇列詳解

首先看乙個問題。給定乙個數列,從左至右輸出每個長度為 k 的數列段內的最小數和最大數 第一行輸出每個區間最小值,第二行輸出最大值 數列長度 n leq 10 6 k leq n 解法 很直觀的一種解法,那就是從數列的開頭,找到這最開始的k個數的最大值,然後後移乙個單元,繼續找到k個數中的最大值。這種...

dp單調佇列(詳解)

我們從最簡單的問題開始 給定乙個長度為n的整數數列a i i 0,1,n 1和窗長度k.要求 f i max,i 0,1,n 1 問題的另一種描述就是用乙個長度為k的窗在整數數列上移動,求窗裡面所包含的數的最大值。解法一 很直觀的一種解法,那就是從數列的開頭,將窗放上去,然後找到這最開始的k個數的最...