在這裡先簡單描述一下單調棧給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2, 1, 4, 5, 1, 3, 3, 他們的寬都是1,其中最大的矩形是陰影部分。單調棧:一種線性資料結構,棧內元素自棧頂到棧底滿足單調性。有單調遞增棧和單調遞減棧。如果要加入棧的元素不滿足單調性,則要將棧頂元素彈出,直到滿足條件為止,然後將該元素入棧
作用:
input:輸入包含多組資料。每組資料用乙個整數n樣例輸入:nn來表示直方圖中小矩形的個數,
,,你可以假定1≤n
≤100000
1\leq n\leq100000
1≤n≤10
0000
。 然後接下來n
nn個整數h1,
...h
n,h_,...h_,
h1,..
.hn
, 滿足0≤h
n≤1000000000
0\leq h_\leq1000000000
0≤hn≤
1000
0000
00。 這些數字表示直方圖中從左到右每個小矩形的高度,每個小矩形的寬度為1
11。 測試資料以0
00結尾。
output:
對於每組測試資料輸出一行乙個整數表示答案。
樣例輸出:721
4513
341000
1000
1000
1000
0
現在,每乙個矩形的高都是已知的,但是矩陣的寬還不清楚。如果要求最大的矩形面積,就要已知矩形的高和寬,則在矩形高已知的情況下,要使矩形面積最大,肯定寬越大,即左端點越靠左,右端點越靠右,矩形的面積才可能最大。那左端點可以確定為往左數第乙個小於此高度的點,右端點可以確定為往右數第乙個小於此高度的點。8
4000
利用這個特點,我們可以使用兩次單調遞減棧,第一次棧找到第乙個小於此高度的右端點,第二次棧找到第乙個小於此高度的左端點。
接下來我們考慮實現,這裡我們並沒有使用stl中的stack,而是自己手寫模擬棧,我認為這樣更方便些。棧用乙個陣列表示,用乙個top表示棧頂指標,top始終指向棧頂的位置。棧中的每乙個元素都是乙個結構體型別,有四個域,儲存它的值,它的陣列下標,它的左端點和右端點的值。因為單調棧的複雜度是線性的,我們使用一次for迴圈就可以完成對乙個端點的查詢。在求乙個端點時,首先考慮要被放入到棧的元素是否小於棧頂元素,若小於,則棧頂元素彈出,並且修改棧頂元素的右端點的值為被放入棧的元素的下標,重複以上步驟,直到大於為止,在一次for迴圈結束後,棧中剩餘元素的右端點就是最又端了。對於求左端點,只不過是將陣列逆序再呼叫一次遞迴棧,原理類似。
如果該題目能夠想到使用單調棧就十分容易了,但是要注意一點,如果變數型別使用int的話會爆精度,所以一定要使用long long!!
#include
using
namespace std;
struct limit
limit()
};intmain()
long
long
int top=0;
limit *q=
new limit [n+1]
;for
(int i=
1;i<=n;i++
)//找到右端點
top++
; q[top]
=p[i];}
while
(top!=0)
limit *qq=
new limit [n+1]
;for
(int i=n;i>=
1;i--
)//找到左端點
top++
; qq[top]
=p[i];}
while
(top!=0)
long
long
int maxn=0;
for(
int i=
1;i<=n;i++
)//求出以每乙個矩形為高的最大面積
cout<
delete
p;delete
q;delete
qq;
cin>>n;
}}
最大矩形 單調棧
題目 給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2,1,4,5,1,3,3,他們的寬都是1,其中最大的矩形是陰影部分。輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 n 100000.然後接下來n個整數h1,hn,滿足 0 h...
貪心 單調棧 最大矩形
貪心 假設當前點為最大矩陣的右下角,向上擴充套件每次取長度的最小值作為矩陣的長。class solution int r matrix.size c matrix 0 size vectorint left r,vector int c,0 for int i 0 i r i int ret 0 f...
85 最大矩形(單調棧)
給定乙個僅包含 0 和 1 的二維二進位制矩陣,找出只包含 1 的最大矩形,並返回其面積。輸入 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 輸出 6這個題可以看成上一題 84.柱狀圖中最大的矩形 單調棧 的拓展,我們一行一行的來分析這個矩陣 第一行 1,0,1,0...