You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

O(NW)时间O(W)空间的多重背包问题实现错误排查求助

多重背包O(W)空间实现的错误排查与测试建议

我帮你梳理下可能导致代码出错的几个核心问题,同时给你一些测试用例和验证思路:


一、代码中的明显错误点

1. 第一个物品的处理逻辑错误

你的代码里单独处理了item == 0的情况,但这部分逻辑存在严重问题:当物品的可拿数量num小于能装下的最大数量时,代码会错误地继续累加价值。比如:

  • 测试用例:输入1 3,物品是1 5 2(重量1,价值5,最多2个)
  • 你的代码会计算出dp_cur[3] = 15,但正确结果应该是10(最多拿2个,总重量2,价值10)

问题出在这段代码:

else {
    dp_cur[start + step * weight] = dp_cur[start + (step - 1) * weight];
}

step > num时,你直接继承了前一个step的价值,相当于继续拿物品,但实际上此时已经不能再拿了。正确的处理应该是:对于第一个物品,dp_cur[j] = min(j / weight, num) * cost,也就是最多拿num个。

你可以直接删掉item == 0的分支,让单调队列的逻辑统一处理所有物品,这样既能避免重复代码,也能修复这个错误。

2. 单调队列的边界处理可能存在疏漏

在非第一个物品的处理中,当step == 1时,你单独计算了dp_cur[start + step * weight],如果测试用例里存在num == 0的物品(虽然题目中k_i应为正整数,但代码鲁棒性不足),会直接出错。另外,当num远大于背包能装下的该物品数量时,队列的pop逻辑是否能正确过滤超出限制的元素,需要用边界测试用例验证。

3. 状态转移的一致性问题

你提到另一个复杂度更差的实现也有同样错误,这大概率是你对多重背包的状态转移理解有偏差——比如混淆了“总重量不超过W”和“恰好装满W”的要求?你的代码中dp[j]定义为总重量不超过j的最大价值,最终取dp_cur的最大值,这部分逻辑是对的,但要确保所有状态转移都严格遵循这个定义。


二、测试用例推荐

你可以用以下测试用例验证代码:

测试用例1:单物品超出数量限制

输入:
1 3
1 5 2
预期输出:10

测试用例2:多物品组合最优解

输入:
2 5
2 3 2
3 4 1
预期输出:7

(取1个重量2价值3的物品+1个重量3价值4的物品,总重量5,价值7)

测试用例3:多物品满背包最优解

输入:
3 10
2 5 3
3 6 2
5 10 1
预期输出:22

(取2个重量2价值5的物品+2个重量3价值6的物品,总重量10,价值22)

测试用例4:物品重量等于背包容量

输入:
2 6
2 4 3
3 5 2
预期输出:12

(取3个重量2的物品,总重量6,价值12)


三、测试用例获取与验证思路

除了自己构造测试用例,你还可以:

  • 构造极端边界情况:比如物品重量远大于背包容量、所有物品重量相同、num为1(退化为01背包)等
  • 参考算法竞赛中的多重背包题目,将代码提交到在线评测平台验证(比如搜索“多重背包问题”相关竞赛题,用题目自带的测试用例校验)

内容的提问来源于stack exchange,提问作者user123213

火山引擎 最新活动