题意;送n头牛回牛棚,每送一头牛消耗的时间为2*Ti 分钟,同时如果第i头牛没有被送回会每分钟啃食Di花朵,求把所有牛送回最少被啃食的花朵
贪心
令sum表示除去第i头牛和第j头牛外,其余没有被送回的牛每分钟啃食花朵的和
假设和j牛相比,先送回i牛更优
即 (sum+Dj)*Ti*2 + sum*Tj*2 < (sum+Di)*Tj*2 + sum*Ti*2
整理得 Ti/Di < Tj/Dj
我们按 Ti/Di 从小到大排序所得的顺序即送回的顺序,被啃食的花朵数处理一下即可
吐槽:mdzz,一开始列不等式的时候忘考虑第另一头牛送回的消耗也要加一起比较,结果复杂度根本降不下来,感谢zgc大神百忙之中找出我这个zz的脑抽
type
rec=record
d,t:longint;
p:double;
end;
var
n,sum :longint;
ans :int64;
i :longint;
a :array[0..100010] of rec;
procedure sort(l,r:longint);
var
i,j:longint;
x:double;
y:rec;
begin
i:=l; j:=r; x:=a[(l+r)>>1].p;
while (i<=j) do
begin
while a[i].p<x do inc(i);
while a[j].p>x do dec(j);
if i<=j then
begin
y:=a[i]; a[i]:=a[j]; a[j]:=y;
inc(i); dec(j);
end;
end;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
begin
read(n);
for i:=1 to n do read(a[i].t,a[i].d);
for i:=1 to n do a[i].p:=a[i].t/a[i].d;
sort(1,n);
sum:=0; ans:=0;
for i:=1 to n do inc(sum,a[i].d);
for i:=1 to n do
begin
dec(sum,a[i].d);
inc(ans,int64(sum)*int64(2)*int64(a[i].t));
end;
writeln(ans);
end.
——by Eirlys