特點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個數)區間的最大值,最小值window position輸入:8 3
1 3 -1 -3 5 3 6 7
輸出:-1 -3 -3 -3 3 3
3 3 5 5 6 7
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 的視窗。現在這個從左邊開始向右滑動,每次滑動乙個單 位,求出每次滑動後視...