var n,m,i,j:longint;
w,v,f:array[0..10001]of longint;
begin
readln(n,m);
for i:=1 to n do readln(w[i],v[i]);
for j:=1 to m do
for i:=1 to n do
if (j>=w[i]) and (f[j-w[i]]+v[i]>f[j]) then f[j]:=f[j-w[i]]+v[i];
writeln(f[m]);
end.
{40}
program n162;
var n,m,i,j:longint;
w,v,f:array[0..10001]of longint;
begin
readln(n,m);
for i:=1 to n do readln(w[i],v[i]);
for i:=1 to m do f[i]:=-maxlongint;[加了这句话后]
for i:=1 to n do
for j:=1 to m do
if (j>=w[i]) and (f[j-w[i]]+v[i]>f[j]) then f[j]:=f[j-w[i]]+v[i];
writeln(f[m]);
end.
{70 (没超时!)}
program n162;
var n,m,i,j:longint;
w,v,f:array[0..10001]of longint;
begin
readln(n,m);
for i:=1 to n do readln(w[i],v[i]);
for i:=1 to m do f[i]:=-maxlongint;
for i:=1 to n do
for j:=w[i] to m do [改成这样后]
if f[j-w[i]]+v[i]>f[j] then f[j]:=f[j-w[i]]+v[i];
writeln(f[m]);
end.
{ACCEPTED}
不用说了这是道完全背包
但是我对初始值为什么赋-MAXLONGINT不理解;
还有为什么我莫名其妙改了第三次那个就AC了呢;
大牛给解释下...
这样处理的确就是放满的情况
我就以01背包为例解释下
如果你初始0的话,最后结果的 f[m] 可能是从某个初始0的节点转移过来(这样就不满了)。
如三个物品:
大小/价值
3/2
2/100
4/2
背包容量:7
如果不要求放满(用0初始化),则我们来看关键的几个f[]的转移:
f[0]: 0
f[1]: 0
f[2]: 100 f[0]+物品2
f[3]: 100 f[1]+物品2
f[4]: 100 f[2]+物品2
f[5]: 102 f[2]+物品1
f[6]: 102 f[3]+物品1
f[7]: 102 f[3]+物品3 or f[4]+物品1
但是要求放满的话,则不会出现有余量的转移:
f[0]: 0
f[1]: 无穷小
f[2]: 100 f[0] + 物品2
f[3]: 2 Comment:如果要放物品2,只能从f[1]转移,但是有余量的 f[1] 加上物品2的价值仍然为无穷小,所以只能放物品1。即为:f[0]+物品1
f[4]: 3 Comment:同上,只能放物品3,f[0]+物品3
f[5]: 102 f[2] + 物品1 or f[3]+物品2
f[6]: 102 f[2] + 物品3 or f[4]+物品2
f[7]: 4 显然放入物品2的不行,于是只能 物品1+物品3
不知道这样说你能不能理解
就是 fpc 版本比较低,或者是优化选项没有打开(可能需要-O2)
在编译的时候没有最优化处理
这样就没有条件判断的短路优化
于是即使当 j 不满足大于等于 w[i] 时仍然会访问 f[j-w[i]],此时 j-w[i] 是负值所以可能会出问题
不过貌似也不太像。。。
还有一种可能是rpless了。。。
在编译的时候没有最优化处理
这两个我都试过了,
给f[0]赋0,然后if (j>=w[i]) and (f[j-w[i]]+v[i]>f[j]) then f[j]:=f[j-w[i]]+v[i];
改成if (j>=w[i]) then if (f[j-w[i]]+v[i]>f[j]) then f[j]:=f[j-w[i]]+v[i];
无效,照样70