給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2, 1, 4, 5, 1, 3, 3, 他們的寬都是1,其中最大的矩形是陰影部分。
輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 <= n <= 100000. 然後接下來n個整數h1, …, hn, 滿足 0 <= hi <= 1000000000. 這些數字表示直方圖中從左到右每個小矩形的高度,每個小矩形的寬度為1。 測試資料以0結尾。
對於每組測試資料輸出一行乙個整數表示答案。
input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0output
84000
如果我們確定了乙個高度,那麼我們必須使左端點盡量靠左,右端點盡量靠右才能使直方圖面積盡量大,還需要注意的是,左右端點之間的「柱子」的高度必須≤
\le≤我們確定的高度。
現在我們只需找到某乙個柱子其左邊和右邊第乙個比它高的柱子的位置,利用單調棧可以很好地解決。
單調棧可以視為一種棧,滿足單側開口,filo的規則。不過單調棧還增加了一條規則:必須保持棧內元素是單增/單減(可以自己設定)的。以單增棧為例,當往棧內壓入元素時,如果棧頂元素比將要壓入的元素小,就可以壓入;如果比它大,我們就需要將棧頂的元素彈出,再去比較新的棧頂元素與要壓入元素的大小,這樣不斷比較不斷彈出,直到棧空或者棧頂元素要比壓入的元素小再壓入。
基於單調棧的這個特性,我們可以找到某乙個元素在左/右邊第乙個小/大於他的元素。以找右邊第乙個小於他的元素為例,我們用單增棧,從左往右將陣列中的元素壓棧,當遇到乙個元素要大於棧頂元素,此時棧頂元素要彈出,而這時也說明了棧頂元素遇到了右邊第乙個小於他的元素,就是這個要壓棧的元素;彈出之後還可以繼續比較後面的棧頂元素,如果還是比棧頂元素小,那麼又可以為新的棧頂元素確定他的右邊第乙個小的元素了。這樣遍歷一遍陣列,實際上就將陣列中所有元素的右邊第乙個小於它的元素給找到了,這樣的時間複雜度是o(n
)o(n)
o(n)
的。回到這個題,利用單調棧,我們可以為每乙個柱子找到其右邊第乙個低於其高度的柱子的位置,同樣,從右往左再遍歷一次,我們又可以獲取每乙個柱子左邊第乙個低於其高度的柱子的位置,這樣我們就能為每乙個柱子求得其所能畫得的直方圖的最大面積。求乙個max的得到這些面積中最大的。該題結束。
本題當時出錯的地方:在臨時變數處爆了int的精度。
給我的debug提了乙個醒:資料的精度和範圍一定要仔細,考慮全面再確定用什麼型別儲存,這裡看著資料的範圍似乎用int就能搞定,但實際上很多地方都有可能超出int,比如最後算每乙個矩形面積的時候的**:
long
long
int max=0;
for(i=
0;i)
long long temp=(r[i]-l[i]-1)*h[i]
這裡看似考慮了超出long long 的情況,但實際上還是漏掉了int型的臨時變數,即當乘積的雙方都是int型時,返回的也是int型的臨時變數,然後再賦給long long的temp,所以,這裡應該將乘積中的某一方換成long long型別的變數,可以通過強制型別轉換,也可以在定義的時候就直接用long long定義。
#include
#include
#include
#include
#include
#include
using
namespace std;
int n;
long
long
int h[
100010];
int st[
100010];
//單增
int top;
int l[
100010];
int r[
100010];
intmain()
top++
; st[top]
=i;//儲存在h中的索引
}while
(top>=0)
top=n;
for(i=n-
1;i>=
0;i--
) top--
; st[top]
=i;//儲存在h中的索引
}while
(top<=n-1)
long
long
int max=0;
for(i=
0;i)printf
("%lld\n"
,max);}
return0;
}
A 最大矩形單調棧解法 Week5作業)
1 是一道經典的單調棧問題 2 利用單調棧計算出當前高度的矩形左右兩邊可以延伸到的寬度 計算出當前矩形左邊第乙個比該矩形高度小的座標 計算出當前矩形右邊第乙個比該矩形高度小的座標 兩者之差,是以當前矩形高度為高的最大矩形的寬度 計算矩形面積,求出最大面積 3 利用乙個單調棧從左往右對矩形高度進行遍歷...
week5 作業A 最大矩形
給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2,1,4,5,1,3,3,他們的寬都是1,其中最大的矩形是陰影部分。input 輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 n 100000.然後接下來n個整數h1,hn,滿足 ...
week5作業題 A 最大矩形
給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2,1,4,5,1,3,3,他們的寬都是1,其中最大的矩形是陰影部分。input 輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 n 100000.然後接下來n個整數h1,hn,滿足 ...