You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

完全背包问题自定义实现与标准解法结果不一致的原因求解

完全背包问题代码错误原因解析

你的代码核心错误点

  • 错误1:物品选择逻辑存在本质缺陷
    你写的逻辑是直接取当前容量下能放入当前物品的最大数量一次性全部放入,完全没有考虑「少放几个当前物品,腾出空间放其他物品总价值更高」的情况。
    举个简单的反例:

两种物品:物品1体积2价值3,物品2体积3价值5,背包容量7
最优解是放2个物品1 + 1个物品2:总占用体积22 +3=7,总价值32 +5=11
按你的逻辑处理物品2时,容量7最多放2个物品2,总价值10,剩余1容量浪费,价值比最优解低,你的代码会直接选中这个更差的结果。

  • 错误2:背包容量遍历方向错误
    完全背包允许物品重复选取,必须从小到大正序遍历容量,这样更新大容量的dp值时,可以复用到当前物品更新过的小容量dp值,实现多次选取同一物品的效果。你用了01背包的倒序遍历逻辑,天然限制了每个物品最多只能选一次,和完全背包的要求冲突。

与正确解法的逻辑差异

正确解法的核心逻辑是「每次决策要不要多拿一个当前物品」,逐次累加实现无限选取的效果,同时每一步都会和全局最优值比较,不会错过混合选品的更优组合:

class Solution:
    def backPackIII(self, A, V, m):
        n = len(A)
        dp = [0] * (m + 1)
        
        for i in range(n):
            # 正序遍历容量,允许重复选取当前物品
            for j in range(A[i], m + 1):
                # 决策:是否多拿一个第i个物品
                dp[j] = max(dp[j], dp[j - A[i]] + V[i])
        
        return dp[m]    

枚举选取数量思路的正确写法(可选)

如果你想保留「枚举物品选取数量」的原始思路,需要在两层循环中间加一层数量枚举,而不是直接取最大数量,这种写法时间复杂度比标准正序解法更高:

def backPackIII(self, A, V, m):
    dp = [0] * (m + 1)
    for i in range(len(A)):
        for j in range(m, A[i]-1, -1):
            max_k = j // A[i]
            # 枚举所有可能的选取数量,逐一比较取最优
            for k in range(1, max_k +1):
                dp[j] = max(dp[j], dp[j - k*A[i]] + k*V[i])
    return dp[-1]

内容的提问来源于stack exchange,提问作者P.He

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 18:45:00