JZOJ 4863 【GDOI2017模拟11.5】Market

Market

题目大意

这里写图片描述
对于每一个计划,每次的消费金额不能超过预算金额,问 Byteasar 可获得的最多价值。

数据范围

n300 m105 ci,Mi109 vi300 ti,Ti300

题解

首先按照 Ti 的值从小到大对每一个计划进行排序,离线操作。
同理,按照 ti 的值从小到大对每一间商店进行排序。
然后每一间商店之多更新背包数组一遍,从小到大枚举时间,每枚举一个新的时间点就用刚开张的商店更新背包数组并同时求得时间点相同的计划的答案。
背包数组的状态 Fi 表示价值和为 i <script type="math/tex" id="MathJax-Element-188">i</script>时的最小代价,这样就可以降低时间和空间复杂度了,转移略。

Code(Pascal)

var
    f:array[-200000..200000] of int64;
    n,m,i,j,k,l,o,oo,u,be:longint;
    mm:int64;
    bz:boolean;
    c:array[0..500,1..3] of int64;
    jh:array[0..120000,1..3] of int64;
    ans:array[0..120000] of int64;
function max(a,b:int64):int64;
    begin
        if a>b then exit(a)
        else exit(b);
    end;
function min(a,b:int64):int64;
    begin
        if a<b then exit(a)
        else exit(b);
    end;
procedure sjzl;
    var
        i,k:longint;
    begin
        randomize;
        for i:=1 to n div 2 do
        begin
            k:=random(n div 2)+n div 2;
            c[0]:=c[i];
            c[i]:=c[k];
            c[k]:=c[0];
        end;
        for i:=1 to m div 2 do
        begin
            k:=random(m div 2)+m div 2;
            jh[0]:=jh[i];
            jh[i]:=jh[k];
            jh[k]:=jh[0];
        end;
    end;
procedure qsort(l,r:longint);
    var
        i,j:longint;
        m,mm:int64;
    begin
        i:=l;
        j:=r;
        m:=c[(l+r) div 2,3];
        repeat
            while c[i,3]<m do inc(i);
            while c[j,3]>m do dec(j);
            if i<=j then
            begin
                c[0]:=c[i];
                c[i]:=c[j];
                c[j]:=c[0];
                inc(i);
                dec(j);
            end;
        until i>j;
        if l<j then qsort(l,j);
        if i<r then qsort(i,r);
    end;
procedure qsortlfsb(l,r:longint);
    var
        i,j:longint;
        m,mm:int64;
    begin
        i:=l;
        j:=r;
        m:=jh[(l+r) div 2,1];
        mm:=jh[(l+r) div 2,2];
        repeat
            while (jh[i,1]<m) or (jh[i,1]=m) and (jh[i,2]<mm) do inc(i);
            while (jh[j,1]>m) or (jh[j,1]=m) and (jh[j,2]>mm) do dec(j);
            if i<=j then
            begin
                jh[0]:=jh[i];
                jh[i]:=jh[j];
                jh[j]:=jh[0];
                inc(i);
                dec(j);
            end;
        until i>j;
        if l<j then qsortlfsb(l,j);
        if i<r then qsortlfsb(i,r);
    end;
begin
    readln(n,m);
    for i:=1 to n do
    begin
        readln(c[i,1],c[i,2],c[i,3]);
        mm:=mm+c[i,2];
    end;
    for i:=1 to m do
    begin
        readln(jh[i,1],jh[i][2]);
        jh[i][3]:=i;
    end;
    sjzl;
    sjzl;
    sjzl;
    qsort(1,n);
    qsortlfsb(1,m);
    k:=0;
    u:=0;
    for i:=-mm to mm do
    f[i]:=214748364700000;
    f[0]:=0;
    for i:=1 to jh[m,1] do
    begin
        bz:=false;
        while (c[k+1,3]<=i) and (k+1<=n) do
        begin
            inc(k);
            for l:=mm downto c[k,2] do
            if f[l-c[k,2]]+c[k][1]<f[l] then
            f[l]:=f[l-c[k,2]]+c[k][1];
            for l:=mm-1 downto 1 do
            f[l]:=min(f[l+1],f[l]);
            bz:=true;
        end;
        be:=0;
        for oo:=u+1 to m do
        begin
            if jh[oo,1]<>i then break;
            while (f[be+1]<=jh[oo,2]) and (be+1<=mm) do inc(be);
            ans[jh[oo,3]]:=be;
        end;
        u:=oo-1;
    end;
    for i:=1 to m do
    writeln(ans[i]);
end.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值