Description
给定
n
n
个物品,每个物品价值为
vi
v
i
,代价为
wi
w
i
。
可以以任意的顺序选择任意数量的物品,但在选择编号为
i
i
的物品后,剩下物品的价值都会减少
wi
w
i
。
要求最大化选择商品的价值之和。
Input
第一行包含两个整数
n
n
。
之后
n
n
行每行包含两个整数
vi,wi。
v
i
,
w
i
。
Output
共一行,表示最大化选择商品的价值之和。
Data Constraint
n≤5000,vi,wi≤105。 n ≤ 5000 , v i , w i ≤ 10 5 。
Sample Input
5
8 2
10 7
5 1
11 8
13 3
Sample Output
27
Solution
显然,先将代价升序排序,贪心地先选代价较小的物品,从而对后面选的造成影响最小。
设
fi,j
f
i
,
j
为选前
i
i
个物品,在其后还要选
j
j
个物品的最优解。
DP式:
fi,j=max( fi−1,j , fi−1,j+1+vi−wi∗j)
f
i
,
j
=
m
a
x
(
f
i
−
1
,
j
,
f
i
−
1
,
j
+
1
+
v
i
−
w
i
∗
j
)
那么答案就是
fn,0
f
n
,
0
。
code
const maxn=5005;
var i,j,n,ans:longint;
w,v:array[1..maxn] of int64;
f:array[0..maxn,0..maxn] of int64;
function max(x,y:int64):int64;
begin
if x>y then exit(x);exit(y);
end;
procedure swap(var x,y:int64);
var t:int64;
begin
t:=x;
x:=y;
y:=t;
end;
procedure qsort(x,y:longint);
var i,j:longint;
k:int64;
begin
i:=x;
j:=y;
k:=w[(i+j) shr 1];
repeat
while w[i]<k do inc(i);
while w[j]>k do dec(j);
if i<=j then begin
swap(w[i],w[j]);
swap(v[i],v[j]);
inc(i);dec(j);
end;
until i>j;
if i<y then qsort(i,y);
if j>x then qsort(x,j);
end;
begin
readln(n);
for i:=1 to n do readln(v[i],w[i]);
qsort(1,n);
for i:=1 to n do
for j:=0 to n-i do
f[i,j]:=max(f[i-1,j],f[i-1,j+1]+v[i]-w[i]*j);
writeln(f[n,0]);
end.