Value
题目描述
数据范围
题解
一开始,先按照
w
数组的值从小到大排一下序,这样就能保证从前往后选时是最优的。
接下来,我们可以考虑动态规划,但是动态规划从前往后做的话我们就不知道后面选某个物品时他此时的价值为多少了。
所以我们倒着做。
F[
动态转移方程显然为
F
[i ][
j
]=max (f[
k
][j -
1
]-(j -
1
)*wi +
vi
)(其中i< k<=n)
但是我们发现这个转移式是
O
(
Code(Pascal)
var
n,j,k,l,i,o,p:longint;
ans:int64;
w,v:array[0..10000] of int64;
qz:array[0..6000] of int64; //后缀和数组
function max(a,b:int64):int64;
begin
if a>b then exit(a)
else exit(b);
end;
procedure sjzl; //随机增量算法,防止快速排序时间超限
var
k,i:longint;
begin
randomize;
for i:=1 to n div 2 do
begin
k:=random(n div 2)+1;
w[0]:=w[i];
w[i]:=w[i+k];
w[i+k]:=w[0];
v[0]:=v[i];
v[i]:=v[i+k];
v[i+k]:=v[0];
end;
end;
procedure qsort(l,r:longint);
var
i,j,m,mm:longint;
begin
i:=l;
j:=r;
m:=w[(l+r) div 2];
mm:=v[(l+r) div 2];
repeat
while (w[i]<m) or ((w[i]=m) and (v[i]>mm)) do inc(i);
while (w[j]>m) or ((w[j]=m) and (v[j]<mm)) do dec(j);
if i<=j then
begin
w[0]:=w[i];
w[i]:=w[j];
w[j]:=w[0];
v[0]:=v[i];
v[i]:=v[j];
v[j]:=v[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
begin
readln(n);
for i:=1 to n do
readln(v[i],w[i]);
sjzl;
qsort(1,n);
for i:=1 to n do
qz[i]:=-maxlongint;
for i:=n downto 1 do
begin
for l:=n-i downto 1 do
qz[l+1]:=max(qz[l+1],qz[l]-w[i]*l+v[i]);
qz[1]:=max(qz[1],v[i]);
end;
for i:=1 to n do
ans:=max(ans,qz[i]);
writeln(ans);
end.