單調棧萌新講解

2022-02-28 23:46:02 字數 1877 閱讀 7490

單調棧

哈。。。怎麼開始介紹這個單調棧是乙個小問題。。。所以就直接講他的功能了:在入棧時遵循單調原則,可以求出乙個元素向左和向右所能擴充套件的最大長度;

具體操作:

例1:求乙個元素的右側的最近比他大的元素位置(bzoj3401);

input:

輸入乙個n代表元素個數,輸入n個元素;

63 2 6 1 1 2

output:

輸出位置,沒有則輸出0;

3 3 0 6 6 0

思路:首先能不能隨便一點,我就是維護乙個棧的單調遞增(不管三七二十一),那麼我要如何利用呢?

①   

3進棧;

②   

2比棧頂元素小,不要;

③   

6比棧頂元素大,進去;

④   

。。。。。等等窩們不是要求乙個元素比他的最近麼?這樣子2都不要了。。然後6過來了還進棧。。這不是背道而馳了。

所以方案錯誤;

那麼不是維護單調遞增,就是維護一下單調遞減唄;

①   3進棧

②   

2比3小進棧

③   

6比2大,咦?一下就是6比2大,而且後面都沒有碰到,所以6一定是2的單側最近,然後2出棧,並且2的答案就是6元素的位置。然後看3,3還是比6小,ok,滿足。最後把6進棧。

④   1進棧

⑤   1進棧

⑥   

2的時候,棧裡面的兩個1出棧,然後2進棧

⑦   

最後注意,棧裡面還有6和2這兩個元素,可惜沒有他們的答案,那就是0;

int a[100005],ans[100005];

struct asd;

stackq;

int main()

return 0;

}

引用黃學長的做法:

倒序維護單調遞減棧,其實也一樣,倒序的時候,碰到元素如果比他大就要把棧裡元素

pop掉,如果比棧頂小的話那就是說棧頂元素位置就是答案;

所以窩們先可以得出乙個小感悟:

即:單調棧就是通過維護棧內元素單調遞增或者單調遞減,判斷棧頂元素和當前元素的關係處理,然後得到窩們想要的答案(其實就是乙個元素向左和向右所能擴充套件的最大長度);

這裡還有一題(poj2796):實際上就是對於乙個元素,求兩端的最長延伸;

題意:給你n個數,求在某段區間的最小值

*這段區間所有元素之和,求最大;

(ps:還是如此窩們只能說我維護乙個單調遞增看看,行不行?不行遞減看看?(或許題目做多了就熟能生巧了吧);我覺得乙個棧存乙個結點的所需要的所以資訊比較好理解,所以上面的**也是這樣。)

這題的思路:

首先區間和,利用字首和,然後減一減就可以搞出來;

那麼就是確定每個元素,當這個元素是最小的時候,我要知道他之前和之和有多少個比他大的,即比他小的最近的兩個端點。

通過上面的寫法,可以搞兩發單調棧搞出那個區間長度;

不過還是很欣賞紫憶的這篇(<=可點 >。<);

維護乙個單調遞增棧,並且細節上處理乙個元素的兩個位置,依次從左往右,在當點元素與棧頂元素比較時;

①   

a[i]>q.top()

那麼就是入棧;

②   

a[i]時,那麼也就是說對於這個元素啊,q.top()的元素的右邊最小就是a[i]位置,那麼a[i]的前延伸要變成出棧頂元素的前延伸,出棧,那麼此時棧不為空的話,棧頂元素的向後延伸位置要變成之前出棧元素的後驅。

③   

期間判斷乙個最大值;

雖然麻煩一點吧,但是還是很妙啊~

也可以兩次,一次操作細節上很多吧;

嘿嘿嘿~~

單調棧講解

以前一直有接觸,但是一直沒單獨進行分析處理 單調棧 維護其中元素單調性的棧 也就是從棧底到棧頂都是有序的 維護 如果入棧的元素滿足單調性,直接入棧 如果不滿足,就讓棧頂元素出棧,直到能讓入棧元素滿足單調性為止,再將元素入棧 已經出棧的元素就被拋棄 題解鏈結 單調棧問題 我們可以用乙個單調棧來維護每個...

專題講解 單調棧

單調棧的核心思想是維護乙個單調遞增或者單調遞減的雙向佇列。佇列中儲存陣列的索引值。我們以一道基本例題為例,了解單調棧的簡單框架。這道題目是一道可以用單調棧解決的問題。我們維護乙個序列,如果進來的數字比隊伍右側索引對應的數字大,彈出佇列右側。class solution object defdaily...

KM演算法萌新講解篇

km演算法 首先了解問題 也就是最大權值匹配 二分圖里,邊帶了權值,求整幅圖里匹配最大 最小的權值 因為接觸匈牙利演算法的時候看的是找物件系列的博文,所以也自己寫一發找物件的博文吧 演算法背景 資訊學院計算機某班級有 位玉樹凌風的男子 小諸,小包,小許,小應,小章 外語學院英語系某班級有 位國色天香...