單調棧
哈。。。怎麼開始介紹這個單調棧是乙個小問題。。。所以就直接講他的功能了:在入棧時遵循單調原則,可以求出乙個元素向左和向右所能擴充套件的最大長度;
具體操作:
例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演算法 首先了解問題 也就是最大權值匹配 二分圖里,邊帶了權值,求整幅圖里匹配最大 最小的權值 因為接觸匈牙利演算法的時候看的是找物件系列的博文,所以也自己寫一發找物件的博文吧 演算法背景 資訊學院計算機某班級有 位玉樹凌風的男子 小諸,小包,小許,小應,小章 外語學院英語系某班級有 位國色天香...