【JZOJ4693】疯狂的火神

来源:互联网 发布:过程控制软件 编辑:程序博客网 时间:2024/05/01 02:07

JZOJ链接 (原题BestCoder Round #59 (div.1) B)
题目大意直接看题吧
首先很容易想到这是一个一维的背包问题
但是由于不同的时间打怪有不同的效益
所以我们需要决定的是打怪的顺序
假设最优答案的打怪顺序为p1,p2,p3…pm
那么对于任意两个相邻怪物pi,pi+1
调换顺序不会使得其更优
由于两个怪物需要打的时间相同
所以调换两个相邻怪物不会使其他怪物的贡献有影响,因此我们只用关心两个相邻怪物就好了
依然是对于怪物i,i+1而言
如果我们先打i,我们失去的收益为这里写图片描述
如果我们先打i+1,我们失去的收益为这里写图片描述
因此如果这里写图片描述,则先打pi更优
移项可得这里写图片描述
由此可得最优的答案顺序中这里写图片描述是递减的
因此我们把怪物的这里写图片描述从大到小排列
之后就是一个一维背包问题了
这里写图片描述表示用i分钟达到的最大收益这里写图片描述
转移公式为这里写图片描述这里写图片描述
最后统计其中最大的这里写图片描述即可

代码

var    a,b,c:array[0..1000] of longint;    rt:array[0..1000] of extended;    f:array[-3000..3000] of int64;    tt,n,m,i,j,k:longint;    ans:int64;function max(a,b:longint):longint;begin    if a>b then exit(a) else exit(b);end;procedure qsort(l,r:longint);var        i,j,t:longint;    mid,et:extended;begin        i:=l;        j:=r;        mid:=rt[(i+j) div 2];        repeat                while rt[i]>mid do inc(i);                while rt[j]<mid do dec(j);                if i<=j then                begin                        et:=rt[i];rt[i]:=rt[j];rt[j]:=et;            t:=a[i];a[i]:=a[j];a[j]:=t;            t:=b[i];b[i]:=b[j];b[j]:=t;            t:=c[i];c[i]:=c[j];c[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;begin    readln(tt);    repeat        readln(n,m);        for i := 1 to n do        begin            readln(a[i],b[i],c[i]);            rt[i]:=b[i]/c[i];        end;        qsort(1,n);        fillchar(f,sizeof(f),0);        for j := 1 to n do        begin            for i  := m downto 0 do            begin                if i-c[j]>=0 then f[i]:=max(f[i],f[i-c[j]]+a[j]-i*b[j]);            end;        end;        ans:=0;        for i := 0 to m do if ans<f[i] then ans:=f[i];        writeln(ans);        dec(tt);    until tt=0;end.
0 0
原创粉丝点击