vijos 1580最大矩形(单调栈)

来源:互联网 发布:unity3d pbrshader 编辑:程序博客网 时间:2024/04/29 06:08

P1580最大矩形Accepted
描述
在x轴上水平放置着N个条形图,这N个条形图就组成了一个柱状图,每个条形图都是一个矩形,每个矩形都有相同的宽度,但是它们的高度并不相同。
比如,图1包含的矩形的高分别为2,1,4,5,1,3,3单位长度,矩形的宽为1单位长度。
你的任务就是计算柱状图中以x轴为底边的最大矩形的面积。图2阴影部分就是上述例子的最大矩形面积。
格式
输入格式

一组数据包含若干行,每行是一个整数N(1≤N≤100,000),表示柱状图包含N个矩形。紧接着N个整数h1,…,hn(0≤ hi ≤20,000, 1≤ i≤ N),表示柱状图中按从左到右顺序给出的矩形的高度。矩形的宽度为1。
输出格式

输出若干行,每行一个整数S,表示以x轴为底边的最大矩形的面积。

思路:每一个点都作为最低点,左边满足的矩形个数和右边满足的矩形个数

program df;
var i,j,n,m,x,y,z,k,t:longint;
ans,s:int64;
a,b,c,d,e,f:array[0..100000] of longint;

function max(x,y:int64):int64;
begin
if x>y then exit(x)
else exit(y);
end;
begin
while not eof do
begin
ans:=0;
fillchar(a,sizeof(a),0);
fillchar(b,sizeof(b),0);
fillchar(d,sizeof(d),0);
fillchar(e,sizeof(e),0);
read(n);
for i:=1 to n do
read(a[i]);
t:=0; b[0]:=0;
for i:=1 to n do
begin
while (t>=0) and (a[b[t]]>=a[i]) do dec(t); //维护左边的点的个数
d[i]:=b[t]+1;
inc(t);
b[t]:=i;
end;
t:=0; b[0]:=n+1;
for i:=n downto 1 do
begin
while (t>=0) and (a[b[t]]>=a[i]) do dec(t); //维护右边点的个数
e[i]:=b[t]-1;
inc(t);
b[t]:=i;
end;
for i:=1 to n do
begin
s:=e[i]-d[i]+1;
s:=s*a[i];
ans:=max(ans,s); //比较每一个点作为最低点,乘积的大小
end;
writeln(ans);
end;
end.

0 0
原创粉丝点击