單調棧詳解和入門例題解析

2021-09-19 15:31:24 字數 1989 閱讀 9014

【單調棧】

基本過程:

讓我們來模擬乙個遞增的單調棧的實現過程,以序列為例。

主要步驟如下:若棧為空或者棧頂元素小於當前元素則壓入,否則彈出棧內比當前元素大的所有元素。

第一步:棧為空,壓入7。此時棧內:7 。

第二步:7比2大,彈出7,壓入2。此時棧內:2 。

第三步:2比5小,壓入5。此時棧內:2 5 。

第四步:5比3大,彈出5,2比3小,壓入3。此時棧內:2 3 。

第五步:3比11小,壓入11 。此時棧內:2 3 11 。

第六步:11比9大,彈出11,3比9小,壓入9 。此時棧內:2 3 9 。

可以在紙上模擬一下這個過程。在這個過程中我們可以跑出以每個元素作為最小值的最左端點下標。

【實現**】

#include using namespace std;

int main()

; int l[10];

stack stk;

for(int i=1;i<=6;i++)

for(int i=1;i<=6;i++)

printf(i<6?"%d ":"%d\n",l[i]);

}

跑出來的結果是1,1,3,3,5,5

同理,我們可以跑出每個元素作為最小值的最右端點的下標,只要從右往左跑就可以了。還有用遞減的單調棧跑出每個元素作為最大值的區間的下標。可以自己嘗試寫一下。時間複雜度為o(n).

【單調棧基礎應用】

1.給定一組數,跑出每個數和他右邊第乙個比他大(小)的數之間有多少個數。

2.給定一串行,尋找某一子串行使得子串行中的最小值乘以子串行的長度最長。

3.給定一串行,尋找某一子串行使得子串行中的最小值乘以子串行所有元素和最大。

【例題講解】

ex1:poj3250

bad hair day

【題解】

題意:每頭牛面朝右邊,只能看到比他矮的牛,詢問所有的牛能看到的牛的數目的期望。

思路:從前往後跑,每次彈出小於等於當前身高的元素,因為如果不高於當前身高就沒辦法越過這個位置看到後面的牛。然後每次加上當前棧內元素個數,即能看到這個位置的前面的牛的數目即可。

【**】

#include #include using namespace std;

#define ll long long

int main()

while(!stk.empty()) stk.pop();

for(int i=n;i>0;i--)

ll ans=0;

for(int i=1;i<=n;i++)

ans=max(ans,a[i]*(r[i]-l[i]+1));

printf("%lld\n",ans);

}}

ex3:poj2796

feel good

【題解】

題意:給定乙個長度為n的序列,輸出區間最小值乘區間和最大的乙個區間的值和左右端點。

思路:跑出以每個位置為最小值的左右區間,用字首和維護區間和,更新最大答案即可。

【**】

#include #include using namespace std;

#define ll long long

const int maxn=1e5+10;

ll a[maxn],sum[maxn];

int l[maxn],r[maxn];

int main()

while(!stk.empty()) stk.pop();

for(int i=n;i>=1;i--)

ll ans=-1,ret,index;

for(int i=1;i<=n;i++)

}printf("%lld\n%d %d\n",ans,l[index],r[index]);

}return 0;

}

單調佇列和單調棧例題

1 單調佇列 給出乙個長度為n的序列和區間長度k 從左向右對每乙個長度為k的區間詢問最大值和最小值。思路 對於最小值,考慮維護乙個遞增的雙端佇列,每次入隊時將隊尾比當前入隊元素的全部刪除,每次取隊首並且判斷是否在當前區間內即可 author hairu,wu from ahut include in...

單調棧與單調佇列簡單例題

poj3250 題意 有n只奶牛排成一列向右看,每頭奶牛只能看到比自己矮的奶牛,即會被高的奶牛擋住後面,問共有多少只奶牛能被看到 思路 考慮每頭奶牛能被前面牛看到的次數,也就是從他左邊開始單調遞減的序列的長度,用單調棧維護即可 include includeusing namespace std c...

單調棧 模板及相應例題

單調棧可以存一段元素每個之前第乙個比它小的元素的下標,沒有的置為 1。以下是單調遞增棧的模板,即棧中的元素為單調遞增的。在入棧之前記錄當前元素左邊第乙個比他小的元素的下標 for int i 1 i n i 以下是單調遞減棧的模板,即棧中的元素為單調遞減的,若當前元素比棧頂元素大,所以棧頂元素為第乙...