單調棧一般可以對於給定的數列,求每個值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.每日溫度 這類題最終要求的結果都是比當前元素更大的下乙個元素的位置 求解思路 就比如上學做操時的排隊,如果你向後望去一馬平川,說明後面沒有比你更高的人,如果後...