01背包问题

能装N件物品,体积最大W,求最大价值v
dp[i][j] 表示前 i 件物品体积不超过 j 的情况下能达到的最大价值,注意是不超过不是等于,所以状态方程不放或者放,j大于等于当前物品重量w才能放
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v[i])

for (int i = 1; i <= N; i++) {
        int w = weights[i - 1], v = values[i - 1];
        for (int j = 1; j <= W; j++) {
            if (j >= w) {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - w] + v);
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }

明显这个二维dp第一维度i可以去掉

for (int i = 1; i <= N; i++) {
        int w = weights[i - 1], v = values[i - 1];
        for (int j = W; j >= 1; j--) {
            if (j >= w) {
                dp[j] = Math.max(dp[j], dp[j - w] + v);
            }
        }
    }

为什么要逆序更新dp[j]?简单来说,dp这时候因为没有i维度,所以每个dp[j]都必须要保证在i-1状态下更新,dp[8]=dp[7],dp[7]=dp[6],这样才对。如果是dp[6]=dp[5],dp[7]=dp[6](dp[6]已经是i状态了)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值