代码随想录-108-背包问题

文章介绍了如何使用动态规划解决背包问题,通过定义dp数组表示在不同物品选择和背包容量下的最大价值,并给出了具体的递推公式。算法实现部分提供了Java代码示例,初始化dp数组,并按物品顺序和背包容量进行双重遍历计算。文章还强调了初始化和递推公式中的关键点。

前言

我在刷卡哥的“代码随想录”,自己的总结笔记均会放在“算法刷题-代码随想录”该专栏下。
代码随想录此题链接
在这里插入图片描述在这里插入图片描述

思路

前提,当前的物品有i+1个,编号为0~i,重量weight和价值value数组如下
weight = {1,3,4}
value = {15,20,30}
通过“动态规划五步曲”,

  1. 确定dp数组含义:dp[i][j]代表,当前可以获取的物品范围在0~i之间(假设物品编号从0开始),当前背包重量为j,dp[i][j]是这个情况下背包可以装下最大的物品价值。
  2. 确定递推公式:
    当前物品大小>背包总容量,dp[i][j]=dp[i - 1][j]
    当前物品大小<=背包总容量,dp[i][j]=max(dp[i - 1][j],dp[i - 1][j - weight[i]] + value[i])
  3. 初始化:当前背包的二维数组全部初始化为0,当物品范围为第一个物品时,背包大小大于等于第一个物品的重量时,接下来的全部可以初始化为第一个物品的价值。
  4. 遍历方向:
    外层遍历,先遍历物品的序号(从第2个物品开始到最后的物品结束);
    内层遍历,遍历背包重量(从背包重量为1开始到背包最大重量);
  5. 举例,如题目
    在这里插入图片描述

在这里插入图片描述

3. 算法实现

public static void main(String[] args) {
   int[] weight = {1,3,4};
   int[] value = {15,20,30};
   int bagSize = 4;
   testWeightBagProblem(weight,value,bagSize);

}

public static void testWeightBagProblem(int[] weight,int[] value,int bagSize){//bagSize背包总重
    int[][] dp = new int[weight.length][bagSize + 1];//所选物品范围(不包括无物品) 和 包重(从0开始到最大重量)
    //默认dp数组全部初始化0
    for(int i = weight[0];i < bagSize + 1;i++){//初始化,包重大于等于第一个物品时,最大价值为第一个物品的价值
        dp[0][i] = value[0];
    }
    //先固定物品范围  再 固定背包重量
    for(int i = 1;i < weight.length;i++){//i物品范围
        for(int j = 1;j < bagSize + 1;j++){//j背包重量
            if(j < weight[i]){
                //背包总容量放不下当前物品(只能是不放该物品的最大价值)
                dp[i][j] = dp[i - 1][j];//不放这个物品,背包重量相同时候的最大大小
            }else{
                //背包总重量放得下当前物品 (那就是 1.不放该物品 2.放该物品  取最大价值情况)
                dp[i][j] = Math.max(dp[i - 1][j],dp[i - 1][j - weight[i]] + value[i]);//不放该物品背包重量相同时的最大价值  与 放该物品最大价值大小(去除该物品前背包的最大价值)
            }
        }
    }

for(int i = 0;i < dp.length;i++){
     for(int j = 0;j < dp[0].length;j++){
         System.out.print(dp[i][j] + " ");
     }
     System.out.println();
    }
}

4. 算法坑点

  1. 初始化,当物品范围为第一个物品时,背包大小大于等于第一个物品的重量时,接下来的全部可以初始化为第一个物品的价值。
  2. 递推公式有条件,
    当前物品大小>背包总容量,dp[i][j]=dp[i - 1][j]
    当前物品大小<=背包总容量,dp[i][j]=max(dp[i - 1][j],dp[i - 1][j - weight[i]] + value[i])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值