題目描述:
最近,afy 決定給 toj 印刷廣告,廣告牌是刷在城市的建築物上的,城市裡有緊靠著的 n
nn 個建築。afy 決定在上面找一塊盡可能大的矩形放置廣告牌。我們假設每個建築物都有乙個高度,從左到右給出每個建築物的高度 h
1h_1
h1,h
2h_2
h2,…,h
nh_n
hn,且 0
00< h
ih_i
hi ≤ 1
,000
,000
,000
1,000,000,000
1,000,
000,
000,並且我們假設每個建築物的寬度均為 1
11。要求輸出廣告牌的最大面積。
輸入格式:
第一行是乙個數 n
nn(n
nn ≤ 1000
,000
1000,000
1000,0
00)。第二行是 n
nn 個數,分別表示每個建築物高度 h
1h_1
h1,h
2h_2
h2,…,h
nh_n
hn,且 0
00< h
ih_i
hi ≤ 1
,000
,000
,000
1,000,000,000
1,000,
000,
000。
輸出格式:
輸出檔案共有一行,表示廣告牌的最大面積。
樣例資料:輸入
65 8 4 4 8 4 輸出
24 題目意思很簡單,方法也很容易想到,對於每棟建築物,都分別找出左邊和右邊第乙個高度小於它的建築物(假設位置分別為 l
ll 和 r
rr),那麼從 l+1
l+1l+
1 到 r−1
r-1r−
1 的高度都大於等於它,此時的最優解為 h∗(
r−l−
1)
h*(r-l-1)
h∗(r−l
−1),掃一遍統計最大值即可
如何找 l,r
l,rl,
r 呢?我們用單調棧(單調遞增)來找,每次加入乙個數,都把在棧中大於等於它的數彈出去,那麼第乙個小於它的位置就在棧頂。正著做一遍求 l
ll,返著做一遍求 r
rr 就可以啦
注意輸入量比較大,建議加讀優
#include
#include
#include
#include
#define n 1000005
using
namespace std;
int h[n]
,l[n]
,r[n]
;stack<
int>s;
intmain()
while
(!s.
empty()
) s.
pop();
for(i=n;i>=1;
--i)
for(i=
1;i<=n;
++i)
max=
max(max,
1ll*h[i]
*(r[i]
-l[i]+1
));printf
("%lld"
,max)
;return0;
}