SOL 1
不难发现,题意就是 010101 背包,用朴素的 010101 背包方式维护即可。
准确地说,用 dp 维护,设 fi,wf_{i,w}fi,w 表示考虑前 iii 个物品,重量不超过 www 的最大价值。
那么我们的决策其实只有第 iii 个物品选/不选。
* 选
此时,重量会累计 wiw_iwi ,价值会累计 viv_ivi 。
考虑此时重量为 www,则选以前,重量是 w−wiw-w_iw−wi 。
所以 fi,w=fi−1,w−wi+vif_{i,w}=f_{i-1,w-w_i}+v_ifi,w =fi−1,w−wi +vi 。
* 不选
此时的情况与 fi−1,wf_{i-1,w}fi−1,w 一摸一样,即 fi,w=fi−1,wf_{i,w}=f_{i-1,w}fi,w =fi−1,w 。
综上所述,dp 的状态转移方程就昭然若揭了,即
fi,w=max(fi−1,w,fi−1,w−wi+vi)f_{i,w}=\max(f_{i-1,w},f_{i-1,w-w_i+v_i}) fi,w =max(fi−1,w ,fi−1,w−wi +vi )
最后答案即为 fn,mf_{n,m}fn,m 。
时间复杂度、空间复杂度均为 O(nm)O(nm)O(nm)。
期望得分 50 分
SOL 2
上面做法的瓶颈是 mmm 大(本题 mmm 可以达到 10910^9109)时时间复杂度就会变得不可接受。
我们惊奇的发现,viv_ivi 和 wiw_iwi 的值域似乎很不同。
也就是说,就算所有东西都买上,总价值也只有 ∑vi≤103×100=105\sum v_i \le 10^3\times 100 = 10^5∑vi ≤103×100=105。
这时候可以想到 dp 的一种经典 trick,状态和目标函数转换。
也就是原来的方程 fi,w=vf_{i,w}=vfi,w =v,我们想成 gi,v=wg_{i,v}=wgi,v =w。
也就是,gi,vg_{i,v}gi,v 表示前 iii 个物品,价值是 vvv 的最小重量。
与前面的决策讨论类似,具体讨论过程留给读者自己思考。
gi,v=min(gi−1,v−vi+wi,gi−1,v)g_{i,v}=\min(g_{i-1,v-v_i}+w_i,g_{i-1,v}) gi,v =min(gi−1,v−vi +wi ,gi−1,v )
答案是最大的 vvv 使得 gn,v≤mg_{n,v}\le mgn,v ≤m。
时间复杂度 O(nV)O(nV)O(nV),空间复杂度 O(nV)O(nV)O(nV)。此处 V=∑viV=\sum v_iV=∑vi 。
这时会 MLE。
我们发现 ggg 的决策,只依赖于上一行。也就是往前的两行三行四行都没有用了,可以不再记录。
采用 滚动数组 的方式进行记录,空间复杂度降为 O(V)O(V)O(V)。
如果不会滚动数组可以借鉴代码或者自行百度。