給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2, 1, 4, 5, 1, 3, 3, 他們的寬都是1,其中最大的矩形是陰影部分。
input這個題我使用方法是單調棧,根據題意可以知道我沒要找到最大的矩形,這裡我們就會考慮到兩個問題:輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 <= n <= 100000. 然後接下來n個整數h1, …, hn, 滿足 0 <= hi <= 1000000000. 這些數字表示直方圖中從左到右每個小矩形的高度,每個小矩形的寬度為1。 測試資料以0結尾。
output
對於每組測試資料輸出一行乙個整數表示答案。
exmaple
sample input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0sample output
84000
一、在知道了矩形的左端點l和右端點r,那麼怎麼去確定這個矩形的高。
二、如果確定了矩形的高度,怎麼確定左端點和右端點。
如果確定了矩形的左端點和右端點,那麼根據「最短板」的思想,這個矩形的高應該是所有高裡面最小的值。而如果確定了矩形的高度,那麼左端點越靠左,右端點越靠右,這樣矩形的面積最大。所以左端點可以確定為往左數第乙個小於此高度的點,右端點可以確定為往右數第乙個小於此高度的點。這裡我們就可以使用單調遞減棧來實現,從直方圖左向右使用單調遞減棧來處理,這樣就可以找到每個矩形的右端點並記錄下來。這裡對於處理完所有的小矩形最後單調棧中剩下的小矩形的右端點都是n。求每個矩形的左端點的過程類似。這裡儲存矩形的左右端點我使用的是兩個索引陣列,即儲存左右端點的索引。
最後根據所有的左右端點求出所有矩形的面積的最大值就行了。
//#include
#include
#define _for(i,a,b) for(int i = (a);i < (b); i++)
#define _rep(i,a,b) for(int i = (a);i <= (b); i++)
#define ll long long
using
namespace std;
const
int n =
100010
;int n;
ll height[n]
;int st[n]
,top;
//單調遞減棧,存index 0~n
int l[n]
,r[n]
;void
getright()
//右端點1~n
st[++top]
= i;
}while
(top >0)
}void
getleft()
//左端點0~n-1
st[++top]
= i;
}while
(top >0)
}int
main()
cout << ans << endl;
}}
在這個實驗中我遇到了乙個關於bits/stdc++.h萬能標頭檔案的一些問題,就是在有些編譯器中,不能使用這個萬能標頭檔案。這是因為bits/stdc++.h不是gnu c++庫的標準標頭檔案,所以在某些編譯器下編譯會出錯,比如msvc中就沒有這個標頭檔案。另外還需要注意這個標頭檔案包含很多不必要的東西,會增加編譯時間。 week5 作業A 最大矩形
給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2,1,4,5,1,3,3,他們的寬都是1,其中最大的矩形是陰影部分。input 輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 n 100000.然後接下來n個整數h1,hn,滿足 ...
A 最大矩形單調棧解法 Week5作業)
1 是一道經典的單調棧問題 2 利用單調棧計算出當前高度的矩形左右兩邊可以延伸到的寬度 計算出當前矩形左邊第乙個比該矩形高度小的座標 計算出當前矩形右邊第乙個比該矩形高度小的座標 兩者之差,是以當前矩形高度為高的最大矩形的寬度 計算矩形面積,求出最大面積 3 利用乙個單調棧從左往右對矩形高度進行遍歷...
WEEK5 周記 作業 單調棧 最大矩形
給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2,1,4,5,1,3,3,他們的寬都是1,其中最大的矩形是陰影部分。輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 n 100000.然後接下來n個整數h1,hn,滿足 0 hi 1...