queue
题目描述
实话实说,给 OIER 大神们排队这种工作是最让人头疼的事情了。因为同学们都有自尊 心,都不愿意排后面.
现在共有 n 个同学要排成一列,每个同学有两个属性:影响力和承受能力。给一个同学 造成的心理创伤指数等于所有在他前面同学的影响力之和减去他的承受能力。
请你帮忙安排一下点名顺序,尽量使受到心理创伤最大的同学少受创伤。
输入
第 1 行是整数 n,表示同学的个数。
第 2~n+1 行每行两个自然数,分别是该同学的影响力和承受能力
输出
输出 1 行 1 个整数,为你安排的顺序中受到心理创伤最大的同学受到的创伤。
Sample input
3
10 3
2 5
3 3
Sample output
2
数据范围
对于 100%的数据,1≤n≤50000,1≤影响力≤10000,1≤承受能力≤10^9。
题解
拿到这道题,刚开始并没有什么思路,就是想着暴力拿个几十分就算了,反正也是蒟蒻,无所谓~
那仔细想一想的话,发现数据范围是这个程度,有没有可能是贪心题?那就想一想怎么证明贪心策略咯,这里引用林厚从老师的证明思路。
NOIP提高组 2012(好像吧)也有一道类似的题目,那题还稍微难一些,需要用到高精度乘除。而这题就简单了,那个加法的运算范围应该是不会上溢的。
下面是Psacal代码:
program ex4;
var a,b,c:array[0..50000] of longint;
i,j,k,v,n,m,min:longint;
sum:int64;
procedure sort(l,r: longint);
var
i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=c[(l+r) div 2];
repeat
while c[i]<x do
inc(i);
while x<c[j] do
dec(j);
if not(i>j) then
begin
y:=c[i];c[i]:=c[j];c[j]:=y;
y:=a[i];a[i]:=a[j];a[j]:=y;
y:=b[i];b[i]:=b[j];b[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
begin
read(n);
for i:=1 to n do
begin
read(a[i],b[i]);
c[i]:=a[i]+b[i];
end;
sort(1,n);
sum:=0;
min:=-maxlongint;
for i:=1 to n do
begin
v:=sum-b[i];
if v>min then
min:=v;
sum:=sum+a[i];
end;
writeln(min);
end.