單調棧總結

2021-08-07 09:48:38 字數 1812 閱讀 1090

單調棧一般可以對於給定的數列,求每個值v在他左右的區間[l,r]是最小值(最大值),通過單調遞增(遞減)棧來實現。

1.用處

求每個值v是哪個區間[l,r]的最小(大)值,一般還會和區間[l,r]有關係

poj2796 feel good

給定數列 要求一

個區間內最小值乘區間和,

的最大值。

poj2559 largest rectangle in a histogram

給定幾個不同高度的矩形,求能畫出的最大矩形面積 

其實就是區間最小值*區間長度,的最大值

poj3494 largest submatrix of all 1』s

給定01矩陣,求全是1的矩陣的最大面積

經過對每一行處理,他可以向上長多少,就轉換成poj2559的直方圖樣子,求區間最小值*區間長度的最大值即可。

poj3250 bad hair day

給定一列牛,求每頭牛能看到他右側幾頭牛,求和。

求比他矮的,所以是遞減棧,而且只需要一側,所以只記錄r也可以。每個值作為區間最大值,的區間長度,求和。

2.步驟(以遞增棧為例)

a.初始化值和區間[l,r]

可用結構體

struct node;

vi題目給定,l,r如果表示vi是[l,r]的最小值,一般初始化為[i,i]

b.for i = 1 to n 遍歷準備入棧

if 棧為空 || 準備入棧元素v[i]  >= 棧頂

入棧else

while 棧不為空 && 棧頂仍然比準備入棧元素大

node

t =

stk.

top();

stk.

pop();

可以根據t,stk.top(),v[i]之間的大小關係,更新stk.top(),v[i]的區間[l,r] // 更新stk.top()前要記得判斷棧是否為空

用t更新答案

退出while 可以將v[i]入棧了

c.在所有元素遍歷完後,棧內仍有元素,可能為答案,所以要清空棧

while 棧不為空

node

t =stk

.top

();stk

.pop

();用t更新stk.top() 

// 更新stk.top()前要記得判斷棧是否為空

用t更新答案

模版#include

#include

#include

using

namespace

std;

const

intmaxn =

8e4+5;

typedef

long

long

ll;

struct

nodecow[

maxn];

stack

<

node

> stk;

intmain()

llans =0;

for(int

i =0

; i < n; i ++)

stk.push

(cow

[i]); }

}while

(!stk

.empty

())

printf

("%lld\n"

,ans);

return0;

}ps:

1.注意根據題目是遞增棧還是遞減棧,是否嚴格增減

2.超時的話手寫棧

3.根據題目,決定答案怎麼更新,不拘泥於形式,比如scu2511

單調佇列與單調棧總結

ref 單調棧解決的是以某個值為最小 最大 值的最大區間,實現方法是 求最小值 最大值 的最大區間,維護乙個遞增 遞減 的棧,當遇到乙個比棧頂小的值的時候開始彈棧,彈棧停止的位置到這個值的區間即為此值左邊的最大區間 同時,當乙個值被彈掉的時候也就意味著比它更小 更大 的值來了,也可以計算被彈掉的值得...

單調棧 佇列總結

51nod 1102 面積最大的矩形 有乙個正整數的陣列,化為直方圖,求此直方圖包含的最大矩形面積。法一 以每個柱子為高,預處理出每個點能夠向兩邊延伸的距離,左找到第乙個比當前點高度小的下標記為i,向右找到第乙個比當前點高度小的下標記為j,那麼此時以這點高度的最大值是f i j i 1 然後用for...

C 單調棧使用總結

相關leetcode題目 496.下乙個更大元素 i 503.下乙個更大元素 ii 556.下乙個更大元素 iii 31.下乙個排列 739.每日溫度 這類題最終要求的結果都是比當前元素更大的下乙個元素的位置 求解思路 就比如上學做操時的排隊,如果你向後望去一馬平川,說明後面沒有比你更高的人,如果後...