Description
“寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎么的心情。能不能说给我听。”
失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的感觉,却不能回忆起她的音容笑貌。
记忆中,她总是喜欢给Eden出谜题,在valentine‘s day的夜晚,两人在闹市中闲逛时,望着礼品店里精巧玲珑的各式玩偶,她突发奇想,问Eden这样的一个问题:有n个玩偶,每个玩偶有对应的价值、价钱,每个玩偶都可以被买有限次,在携带的价钱m固定的情款下,如何选择买哪些玩偶以及每个玩偶可以买多少个,才能使得选择的玩偶总价钱不超过m,且价值和最大。
众所周知的,这是一个很经典的多重背包问题,Eden很快解决了,不过她似乎因为自己的问题被飞快解决感到了一丝不高兴,于是她希望把问题加难:多次询问,每次询问都将给出信的总价钱,并且会去掉某个玩偶(及这个玩偶不能被选择),再问此时的多重背包的答案(即前一段所叙述的问题)。
这下Eden犯难了,不过Eden不希望自己被难住,你能帮帮他么?
Input
从文件bag.in看读入数据。
第一行一个数n,表示有n个玩偶,玩偶从0开始编号。
第二行开始后面的n行,每行三个数ai,bi,ci,分别表示买一个第i个玩偶需要的价钱,获得的价值以及第i个玩偶的限购次数。
接下来的一行为q,表示询问次数。
接下来q行,每行两个数di,ei表示每个询问去掉的是哪个玩偶(注意玩偶从0开始编号)以及该询问对应的新的总价钱数。(去掉操作不保留,即不同询问互相独立)
Output
输出 q行,第 i行输出对于第 i个询问的答案。
Solution
先预处理出f1[i,j],为前i个物品,用了j钱的最大价值,
同理我们再预处理出f2[i,j],为i到n个物品,用了j钱的最大价值。
于是对于每次询问,我们可以枚举z,求max(f1[x-1,z]+f2[x+1,y-z])即可。
代码
1 var 2 n,m,ans:longint; 3 a,b,c:array [0..1001] of longint; 4 f1,f2:array [0..1001,0..1001] of longint; 5 function max(o,p:longint):longint; 6 begin 7 if o>p then exit(o); 8 exit(p); 9 end; 10 11 procedure init; 12 var 13 i,j,k:longint; 14 begin 15 readln(n); 16 for i:=1 to n do 17 readln(a[i],b[i],c[i]); 18 for i:=1 to n do 19 for j:=1000 downto 0 do 20 begin 21 f1[i,j]:=f1[i-1,j]; 22 for k:=1 to c[i] do 23 if j>=k*a[i] then 24 f1[i,j]:=max(f1[i,j],f1[i-1,j-k*a[i]]+k*b[i]) 25 else break; 26 end; 27 for i:=n downto 1 do 28 for j:=1000 downto 0 do 29 begin 30 f2[i,j]:=f2[i+1,j]; 31 for k:=1 to c[i] do 32 if j>=k*a[i] then 33 f2[i,j]:=max(f2[i,j],f2[i+1,j-k*a[i]]+k*b[i]) 34 else break; 35 end; 36 end; 37 38 procedure main; 39 var 40 i,j,x,y:longint; 41 begin 42 readln(m); 43 for i:=1 to m do 44 begin 45 readln(x,y); 46 ans:=0; 47 for j:=0 to y do 48 ans:=max(ans,f1[x,y-j]+f2[x+2,j]); 49 writeln(ans); 50 end; 51 end; 52 53 begin 54 init; 55 main; 56 end.
原文地址:https://www.cnblogs.com/zyx-crying/p/9493707.html