單調棧應用POJ3250 單調序列

2021-08-28 10:27:45 字數 2497 閱讀 3195

參考:

單調棧,顧名思義,是棧內元素保持一定單調性(單調遞增或單調遞減或是其他性質)的棧。

我們假如有這樣乙個問題(poj3250):給定一組數,針對每個數,尋找它和它右邊第乙個比它大的數之間有多少個數。

如果用樸素的解法就會是雙層for迴圈遍歷,時間複雜度達到o(n^2),利用單調棧思想的解法則會降至限行時間o(n)

給乙個序列10,3,7,4,12,我們將他們看作是一站好隊的人,將問題看作每個人看看自己右邊比自己高的人離自己有多遠

最開始,10先站到一邊(進棧),等待比他高的人被發現(被遍歷到),接下來輪到3,他顯然不比站到一邊的人(10)高,那就也和10一起站(進

棧),來等比他高的人被發現.接下來到了7,這時候棧頂(3)大喊:教官,我找到右邊比我高的人了,3完成了任務,高高興興出棧走了

(也就是說,在遍歷過程中,比棧頂元素小的可以直接進棧,作為新的棧頂,它一定比棧裡其它元素更早的發現比它大的右邊元素).

棧裡就剩下了10,10和7一比較,發現7還沒自己高,沒辦法,還得繼續等,7也順勢站到一邊(進棧),等待比自己高的人...迴圈往復

ac**

#include#include#include#includeconst int inf = 0x3f3f3f3f;

typedef long long ll;

using namespace std;

//單調棧設定

//位置進棧,輸入輸出

//最後放置乙個哨兵

//記錄位置陣列

int main()

st.push(bj);

} }

printf("%lld",ans);

return 0;

}

給定乙個n個整數的序列以及乙個非負整數d,請你輸出這個序列中有多少個連續子串行(長度大於1),滿足該子串行的最大值最小值之差不大於d。

連續子串行:序列1 2 3中長度大於1的連續子串行有:

1 2

2 3

1 2 3

第一行包含兩個整數n,d。

接下來一行包含n個整數。

輸出乙個整數,表示滿足條件的連續子串行個數。

8 5

5 5 4 8 -10 10 0 1

7
滿足條件的連續子串行有:

5 55 5 45 5 4 85 45 4 8

4 8

0 1

這道題被提示用單調棧的時候,我是一臉懵逼的,想維護乙個單調遞增或者單調遞減的單調棧,仔細思考思考發現都很難行通.

這是一開頭對單調棧的解釋:  單調棧,顧名思義,是棧內元素保持一定單調性(單調遞增或單調遞減或是其他性質)的棧。

那麼這道題,非單調遞增也不是單調遞減,於是它便一定是滿足其它性質的棧.

這個性質就是棧裡的元素可以滿足題目的條件:滿足該子串行的最大值最小值之差不大於d。

用做例子,我們有下面的乙個序列a,求滿足最大值最小值的差不超過5的子串行個數

5 5 4 8 -7 -10 10 0 1

演算法的一開始自然是5先進棧,然後整個棧的最大值最小值自然先都更新成為5,然後開始遍歷整個序列,輪到第二個5,它的數值

在整個棧的最大值和最小值相差都不大於5,因此他可以進棧,同樣的,4和8也都統統進入,整個棧的最小值為4,最大值為8,每乙個

將要進棧的元素,都可以和棧裡的元素組成連續的滿足條件的子串行.

具體來說,每乙個元素如果能滿足條件進棧,滿足條件的子串行

總數會再加上棧中的元素個數.(比如8進棧的時候,棧中已經有5 5 4, 於是滿足條件的子串行總數就會+3 (4 8) (5 4 8) (5 5 4 8) )

到了-7,他不滿足和棧中最大值最小值相差不大於5這個條件,於是棧清空,停! 不能急著清空,我們需要多乙個判斷,我們考察這樣一種情況

棧中元素(20 15),當前元素為10,這時,20是要丟掉的,但是15是要保留的.

也就是說,從棧頂向下,和當前元素差不大於5的還是可以保留的,直到碰到第乙個破壞了這種性質的元素停止,保留的方法是引入了乙個輔助棧(具體看**吧)

經過判斷,-7的確會讓棧中元素都清空,清空結束後,-7進入棧中. 接下來是-10進棧,10清空了棧進棧....迴圈往復

**(筆記本連不上網了,只能這樣了.**也懶得精簡了,嘿嘿嘿):

最後廢話一句,類似這種序列組合的題目,都可以想想能不能用單調棧做

POJ 3250 單調棧模板

題意 從左右給你n頭都面向右牛的高度,每頭牛能被左邊的牛看到當且僅當自己的身高比他低且中間沒有障礙物 求每頭牛能看到的牛數量之和 include include include include include include include include include include inclu...

POJ 3250 單調堆疊

其實今天是第一次聽說這個資料結構。順便ac了一道題目 所以這個堆疊顯然會滿足一些條件 1.對於所有當前步驟壓入堆疊的元素e,棧中的其餘元素都是 遞增 或遞減 的大於 或小於 e 2.對於彈出的所有元素,一定全都 小於或大於e 這個題目第一眼看到應該是乙個 n 2 的暴力搜尋,但是明顯如果用暴力搜尋的...

poj3250(單調棧模板題)

題意 求序列中每個點右邊第乙個 自身的點的下標。思路 簡單介紹單調棧,主要用來求向左 右第乙個小於 大於自身的下標,直接求的話複雜度為o n2 而單調棧只有o n 利用好單調棧十分有用。乙個元素向左遍歷的第乙個比它小的數的位置就是將它插入單調棧時棧頂元素的值,若棧為空,則說明不存在這麼乙個數。然後將...