以前一直有接觸,但是一直沒單獨進行分析處理
單調棧:維護其中元素單調性的棧
也就是從棧底到棧頂都是有序的
維護:如果入棧的元素滿足單調性,直接入棧;如果不滿足,就讓棧頂元素出棧,直到能讓入棧元素滿足單調性為止,再將元素入棧
(已經出棧的元素就被拋棄)
題解鏈結
單調棧問題
我們可以用乙個單調棧來維護每個矩陣的高度和寬度,
當前矩陣高於棧頂,進棧
當前矩陣a小於棧頂時,直到棧為空或者棧頂矩形的高度比當前矩形小。在出棧過程中,我們累計被彈出的矩形的寬度和。每彈出乙個矩形,就用他的高度(他指被彈出的矩陣)乘上累計的寬度取更新答案,因為每次彈出的高度要比上次彈出的小,相當於依次求以從左往右以每個矩陣高的面積(如圖所示)。整個出棧過程結束後,我們把乙個高度為當前矩陣高度,寬度為累計值的新矩陣入棧。
全部掃瞄過後,我們要將棧內剩餘矩陣依次彈出,並利用相同的方法更新答案。
給乙個01矩陣,問最大的全1矩陣是多少?
題解:先預處理,求出每一行位置上連續的最大的1的矩陣的
高度是多少,再對每一行進行乙個單調棧處理即可
stl的stack版
typedef pair<
int,
int>pa;
int n, m;
int a[
2005][
2005];
pa f[
2005];
stacks;
intmain()
}int ans =0;
pa v;
for(
int i =
1; i <= n; i++
) s.
push
(make_pair
(v.first, a[i]
[j]));
}}}printf
("%d\n"
, ans);}
return0;
}
手寫stack版
for(int i=1;i<=n;i++)
else
st[++top]
=id;//將最後一次出棧的棧頂元素延申併入棧
ri[i]
[id]
=ri[i]
[j];}}
}
給你乙個n * m(1e5 * 100)的矩陣和k(1e5)個黑點,黑點會給定座標,問有多少個不含這些黑點的子矩形。
參考**
這個講的巨詳細
題解:相當於每次從乙個矩陣的最右下角開始加乙個一列的矩陣,加乙個兩列的矩陣,加乙個三列的矩陣…
#include
using namespace std;
typedef
long
long ll;
int b[
100010][
110]
, up[
110]
;int
main()
}for
(int i=
0; i
) ll ans=0;
for(
int i=
1; i<=n; i++)}
for(
int j=
1; j<=m; j++)}
}printf
("case #%d: %lld\n"
,++cas, ans);}
return0;
}
專題講解 單調棧
單調棧的核心思想是維護乙個單調遞增或者單調遞減的雙向佇列。佇列中儲存陣列的索引值。我們以一道基本例題為例,了解單調棧的簡單框架。這道題目是一道可以用單調棧解決的問題。我們維護乙個序列,如果進來的數字比隊伍右側索引對應的數字大,彈出佇列右側。class solution object defdaily...
單調棧萌新講解
單調棧 哈。怎麼開始介紹這個單調棧是乙個小問題。所以就直接講他的功能了 在入棧時遵循單調原則,可以求出乙個元素向左和向右所能擴充套件的最大長度 具體操作 例1 求乙個元素的右側的最近比他大的元素位置 bzoj3401 input 輸入乙個n代表元素個數,輸入n個元素 63 2 6 1 1 2 out...
單調棧 模板 單調棧模板
biu 單調棧主要用於求取左邊第乙個比它大,或者比它小的數。就比如站隊隨便排成一列,可以求到每個人後面第乙個比他高的人。同理可以推廣至右邊,比它矮均可。這就是單調遞增棧 遞減棧,從前至 棧,從後向前入棧的區別了。單調棧比較抽象,非常具有智慧型的想法,可應用的場景相當少,根據幾個經典題目體會它的用法會...