二维数组与滚动数组解决背包问题

关于背包问题及其变式是我们在面试中经常遇见的问题,同时背包问题也是常见的动态规划问题。
解决这类问题通常是走一步看一步,即利用数组来记录上一步的结论,再与当前进行比较。
例如01背包问题

  1. 那么首先需要确定dp数组的含义,我们可以假设一个场景,模拟从0-n个物品中挑选0-m重量的物品
    这个模拟有两个变量那么最适合使用二维数组来模拟,二维数组的右下角就是最终的答案。理解这一点很重要。
  2. 接下来就是递推公式,当前项如何得出呢?答案的·关键是取该物品还是不取,取该物品就是dp[i-weight[i]]+value[i],不取就是dp[i-1][j],取与不取哪一项是最大值就是答案
  3. 接下来就是初始化,即第0个物品中挑选出0-m的重量,很显然只要容量到了第0个物品的重量就可以将其放入
for(let j=weight[0];j<=size;j++){
	dp[0][j] = value[0];
}
  1. 遍历顺序就是经典的从前往后遍历最好(便于理解),其实左右上下顺序都可以,只要有上一层的数据

完整代码:

function testWeightBagProblem (weight, value, size) {
    // 定义 dp 数组
    const len = weight.length,
          dp = Array(len).fill().map(() => Array(size + 1).fill(0));

    // 初始化
    for(let j = weight[0]; j <= size; j++) {
        dp[0][j] = value[0];
    }

    // weight 数组的长度len 就是物品个数
    for(let i = 1; i < len; i++) { // 遍历物品
        for(let j = 0; j <= size; j++) { // 遍历背包容量
            if(j < weight[i]) dp[i][j] = dp[i - 1][j];
            else dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
        }
    }

    console.table(dp)

    return dp[len - 1][size];
}

function test () {
    console.log(testWeightBagProblem([1, 3, 4, 5], [15, 20, 30, 55], 6));
}

test();

优化:大家有注意到每次只是使用了上一层的数据,那么其实可以将矩阵压缩成一层,但是有个问题得注意,我们是一直在操作同一个数组,如果依旧是从头再来的话,后面的结果是没法参考上一层的数据,因为都被这一层给覆盖掉了。所以从后往前遍历时唯一解,毕竟参考的数据是前面,只要从后面来即可。

完整代码:


function testWeightBagProblem(wight, value, size) {
  const len = wight.length, 
    dp = Array(size + 1).fill(0);
  for(let i = 1; i <= len; i++) {
    for(let j = size; j >= wight[i - 1]; j--) {
      dp[j] = Math.max(dp[j], value[i - 1] + dp[j - wight[i - 1]]);
    }
  }
  return dp[size];
}


function test () {
  console.log(testWeightBagProblem([1, 3, 4, 5], [15, 20, 30, 55], 6));
}

test();
  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值