您的位置:首页 > 编程语言

发射站(Pascal)

2017-08-27 16:07 127 查看

发射站

(本题来自某网站,数据可能和网上流传的不同)

题目

题目描述

某地有N个能量发射站排成一行,每个发射站i都有不相同的高度Hi,并能向两边(当然两端的只能向一边)同时发射能量值为Vi的能量,并且发出的能量只被两边最近的且比它高的发射站接收。显然,每个发射站发来的能量有可能被0或1或2个其它发射站所接收,特别是为了安全,每个发射站接收到的能量总和是我们很关心的问题。由于数据很多,现只需要你帮忙计算出接收最多能量的发射站接收的能量是多少。

输入样例

第一行,一个整数N。

第二到N+1行,第i+1行有两个整数Hi和Vi,表示第i个发射站的高度和发射的能量值。

输出样例

输出仅一行,表示接收最多能量的发射站接收到的能量值,答案不超过longint。

样例输入

3

4 2

3 5

6 10

样例输出

7

数据范围

对于40%的数据,1<=N<=5000;1<=Hi<=100000;1<=Vi<=10000;

对于70%的数据,1<=N<=100000;1<=Hi<=2000000000;1<=Vi<=10000;

对于100%的数据,1<=N<=1000000;1<=Hi<=2000000000;1<=Vi<=10000。

思路

对于这道题,我们可以通过维护一个栈来解决。

栈中保存的是a[i]之前的所有符合条件的(何为符合条件?即栈中形成一个不上升序列)所有数。

处理a[i]时,将a[i]加入栈,从后向前找,将所有比他矮(或相等)的发射塔全部移除栈,直到有一个发射塔比它高时停止。

代码

var n,i,l,ans:longint; num,p,h,v:array [0..1000001] of longint;

procedure put(x:longint);
var j:longint;
begin
j:=l;
while (h[p[j]]<=h[x]) and (j>=1) do
dec(j);
l:=j+1;
p[l]:=x;
end;

begin
readln(n);
for i:=1 to n do
read(h[i],v[i]);
p[1]:=1;
l:=1;
for i:=2 to n do
begin
put(i);
if p[1]<>i then num[p[l-1]]:=num[p[l-1]]+v[i];
end;
for i:=1 to n do p[i]:=0;
p[1]:=n;
l:=1;
for i:=n-1 downto 1 do
begin
put(i);
if (p[1]<>i) then num[p[l-1]]:=num[p[l-1]]+v[i];
end;
ans:=0;
for i:=1 to n do
if ans<num[i] then ans:=num[i];
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  pascal 编程题