單調棧與單調佇列入門

2021-10-20 03:26:11 字數 2535 閱讀 4051

特點1:top指向最後乙個數所在位置

特點2:後進先出

特點3:遞增或遞減 ****

例題:poj2796

大意:求乙個區間,這個區間內 所有數的和sum*區間內min 的值 相比其他區間大

輸入:6

3 1 6 4 5 2

輸出:60

3 5

問題:

求出每個數在哪個區間內最小: 區間怎麼求 ?

將這個數 * 區間總值:總值怎麼算?

思路:

標記每個數的左右邊界是本身 3 [1,1] 1 [ 2, 2] 6 [ 3, 3 ] … 之後,依次入棧。

入棧前將棧頂元素與之比較 若棧頂元素較大

目的:在其入棧時更改左區間,保證棧內遞增,棧內元素的左區間確定;在其出棧時更改右區間,保證了左右區間最大化。

用 pre[ ]陣列儲存各個 1-i 的區間值和

之後令 a[ i ]*(pre[右]- pre[左])

**:

#include

#include

#define ll long long

using

namespace std;

const

int n=

1e7+10;

ll n,pre[n]

;ll a[n]

,l[n]

,r[n]

;ll s[n]

,top=0;

int t=1;

intmain()

a[n+1]

=-1;

for(

int i=

1;i<=n+

1;i++

) s[

++top]

= i;

//入棧

} ll ans=-1

,ansl,ansr;

for(

int i=

1;i<=n;i++)}

printf

("%lld\n%lld %lld"

,ans,ansl,ansr);}

return0;

}

特點1: head 指向最前乙個數的前乙個位置

特點2: tail 指向最後乙個數所在的位置

特點3: 可遞增或遞減

例題:poj-2823

大意:求滾動屏(顯示3個數)區間的最大值,最小值

輸入:8 3

1 3 -1 -3 5 3 6 7

輸出:-1 -3 -3 -3 3 3

3 3 5 5 6 7

window position

minimum

maximum

[1 3 -1] -3 5 3 6 7-33

1 [3 -1 -3] 5 3 6 7-33

1 3 [-1 -3 5] 3 6 7-35

1 3 -1 [-3 5 3] 6 7-35

1 3 -1 [-3 5 3] 6 736

1 3 -1 -3 5 [3 6 7]37

**:

#include

#include

using

namespace std;

const

int n=

1e6+20;

const

int m=10;

const

int inf=

0x3f3f3f3f

;//無窮大

int n,k;

int a[n]

;int ansmin[n]

,ansmax[n]

;int que[n]

,head,tail,t=1;

intmain()

head = tail =0;

for(

int i=

1;i<=n;i++

)//求max序列,同上

for(

int i=

1;i<=n-k+

1;i++

)printf

("%d%c"

,ansmin[i]

,i == n-k+1?

'\n'

:' ');

for(

int i=

1;i<=n-k+

1;i++

)printf

("%d%c"

,ansmax[i]

,i == n-k+1?

'\n'

:' ');

}return0;

}

相同點:都將數依次入棧或入列,其間要保證其遞增或遞減,若不滿足的數,則令其出棧或出隊,並且更新部分所求,最終得出所求

不同點

單調棧以及單調佇列入門

一 單調棧 單調棧是指乙個棧內部的元素具有嚴格單調性的一種資料結構,分為單調遞增棧和單調遞減棧。其具有以下兩個性質 1,滿足棧底到棧頂的元素具有嚴格單調性。2,滿足棧的先進後出特性,越靠近棧頂的元素越後出棧。元素進棧過程 對於乙個單調遞增棧來說,若當前進棧的元素為a,如果a 棧頂元素,則直接將a進棧...

單調佇列 入門

今天寫了人生中第乙個單調佇列,激動ing 先看一道單調佇列的入門題 乙個含有n項的數列 n 2000000 求出每一項前面的第m個數到它這個區間內的最小值。先寫出動規方程 f i min j合法 很明顯的,這是乙個n 2的動規,但是,我們可以注意到,數列中有些數無論如何都不會被選到.如 1 2 8 ...

單調佇列入門

單調佇列是一種佇列 廢話 其中佇列的元素保證是單調遞增或者是單調遞減的 那麼隊首的元素不就是最小 或最大 的嗎?我們結合具體的題目來看看吧 傳送門 p1886 滑動視窗 現在有一堆數字共n個數字 n 10 6 以及乙個大小為k 的視窗。現在這個從左邊開始向右滑動,每次滑動乙個單 位,求出每次滑動後視...