SOJ 393 廣告印刷

2021-08-29 13:47:57 字數 1828 閱讀 9054

題目描述:

最近,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;

}