Market
题目大意
对于每一个计划,每次的消费金额不能超过预算金额,问
Byteasar
可获得的最多价值。
数据范围
n≤300 , m≤105 , ci,Mi≤109 , vi≤300 , ti,Ti≤300
题解
首先按照
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.