【JZOJ4710】Value

来源:互联网 发布:小号托管平台源码 编辑:程序博客网 时间:2024/05/21 08:28

JZOJ链接
题目很简短,这里就不说大意了
和之前疯狂的火神一题一样,我们首先考虑选择物品的顺序
设答案的选择顺序为A1,A2,...Am
其中物品Ai对后面物品的损失为Wi(mi)
为了尽可能的避免损失,我们应该把Wi较大的物品放到后面
因此我们物品的选择顺序中Wi是升序排列的
首先我们把物品按Wi降序排序
然后就可以dp啦
Fi,j为在前i个物品中选择了后j个(为了满足我们的物品选择顺序)
转移方程为Fi,j=max(Fi1,j,Fi1,j1+ViWi(j1))
取Max作答案即可。

代码

var    v,w:array[0..5000] of longint;    f:array[0..5000,0..5000] of int64;    n,i,j:longint;    ans:int64;procedure qsort(l,r:longint);var        i,j,mid,t:longint;begin        i:=l;        j:=r;        mid:=w[(i+j) shr 1];        repeat                while w[i]>mid do inc(i);                while w[j]<mid do dec(j);                if i<=j then                begin                        t:=w[i];                        w[i]:=w[j];                        w[j]:=t;            t:=v[i];            v[i]:=v[j];            v[j]:=t;                        inc(i);                        dec(j);                end;        until i>j;        if j>l then qsort(l,j);        if i<r then qsort(i,r);end;function max(a,b:int64):int64;begin    if a>b then exit(a) else exit(b);end;begin    readln(n);    for i := 1 to n do        readln(v[i],w[i]);    fillchar(f,sizeof(f),0);    qsort(1,n);    ans:=0;    for i  := 1 to n do        for j := 1 to i do        begin            f[i,j]:=max(f[i-1,j],f[i-1,j-1]+v[i]-w[i]*(j-1));            ans:=max(ans,f[i,j]);        end;    writeln(ans);end.
0 0