美文网首页
动态规划-背包问题(1)-01背包

动态规划-背包问题(1)-01背包

作者: Nick是老外 | 来源:发表于2021-09-14 11:02 被阅读0次
image

01背包

有N件物品和一个最多能被重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

image
问题:背包容量为4,物品以及其重量和价值如下表所示,问背包能背的最大价值是多少?
image.png

01背包——二维dp数组解法

动态方程:int[][]dp = new int[n][bagWeight+1],其中n为物品的个数,bagWeight为背包的容量
dp[i][j]表示从[0-i]中挑选物品,放入容量为j的背包中,价值总和最大是多少
二维dp数组如下图所示:

image.png
初始化:背包重量为0,总价值为0;当只装入第一个背包且背包重量大于等于weight[0]时,dp[0][j]=val[0]
image.png
动态转移:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
image.png
Java代码
  // 二维dp数组01背包 时间复杂度 O(n^2)
    public static void backPack2(int []w,int[] val,int bagWeight){
        int n = w.length;
        //dp[i][j]表示从[0-i]中挑选物品,放入容量为j的背包中,价值总和最大是多少
        int[][]dp = new int[n][bagWeight+1];
        //初始化
        for(int i=0;i<dp.length;i++){
            dp[i][0] = 0;//背包容量为0时,放入物品的价值为0
        }
        for(int j = w[0];j<=bagWeight;j++){
            dp[0][j] = val[0];//只装入第一个物品时  ,放入物品的价值就是val[0]
        }
        for(int i=1;i<dp.length;i++){//遍历物品
            for(int j=1;j<dp[0].length;j++){//遍历背包容量
                if(j<w[i]) dp[i][j] = dp[i-1][j];
                else dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-w[i]]+val[i]);
            }
        }
        System.out.println("放入物品的最大价值:"+dp[n-1][bagWeight]);
    }

01背包——一维dp数组解法

动态方程:int[] dp = new int[bagWeight+1];,其中bagWeight为背包的容量
dp[j]表示表示背包容量为j时,能获得的最大价值
初始化:dp[0] = 0,背包容量为0所背的物品的最大价值就是0。
递归公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
Java代码

    //一维dp数组(滚动数组) 时间复杂度O(n)
    public static void backPack(int []w,int[] val,int bagWeight){
       //定义dp数组表示dp[j]表示背包容量为j时,能获得的最大价值
       int[] dp = new int[bagWeight+1];//初始化全为0
       //遍历顺序:先遍历物品在遍历背包的重量;
        for(int i =0;i<w.length;i++){
            //01背包内嵌的循环是从大到小遍历,为了保证每个物品仅被添加一次。
            for(int j =bagWeight;j>=w[i];j--){
                dp[j] = Math.max(dp[j],dp[j-w[i]]+val[i]);
                //dp[j-w[i]]+val[i] 表示加上第i个物品的后的总价值
            }
        }
        for(int j=0;j<=bagWeight;j++){
            System.out.println("背包容量为"+j+"时,dp["+j+"]="+dp[j]+" ");
        }
        System.out.println("放入物品的最大价值:"+dp[bagWeight]);
    }

倒叙遍历是为了保证物品i只被放入一次!。但如果一旦正序遍历了,那么物品0就会被重复加入多次!

参考:代码随想录-背包理论

相关文章

  • 算法学习收藏

    动态规划问题 动态规划(最优子结构和重叠子问题的比较) 动态规划解决01背包问题 01背包问题 最优二叉查找树 《...

  • 动态规划-背包问题(1)-01背包

    01背包 有N件物品和一个最多能被重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[...

  • Algorithm进阶计划 -- 动态规划(下)

    经典动态规划背包问题最长子序列问题 1. 背包问题 1.1 0-1 背包问题 0-1 背包问题,描述如下: 上面...

  • 背包

    背包问题九讲笔记_01背包背包问题是动态规划中最基本的题目。 动态规划的4步骤:1.找出子结构2.递归3.自底而上...

  • 背包入门

    背包,是动态规划里一类典型的问题,主要有:01背包,完全背包,多重背包,混合背包,二维费用背包,分组背包,有依赖背...

  • 算法-动态规划-背包问题

    背包问题是基础的动态规划问题,包含了0-1背包,完全背包,多重背包等。 0-1背包 存在容量为 的背包 , 件体...

  • 2.3 记录结果再利用的“动态规划”

    2.3.1 记忆化搜索与动态规划 1. 01背包问题 //// Created by Nathan on 15/...

  • 背包问题

    背包问题属于典型的动态规划问题。这里我们将详细介绍0-1背包,完全背包和多重背包问题 一、 0-1背包 有N件物品...

  • 动态规划

    0-1背包问题 自己实现的0-1背包问题的动态规划解法,先贴上吧,动态规划原理解释有空再写。

  • 初识动态规划

    0-1 背包问题 备忘录 动态规划-二维数组 动态规划-一维数组 0-1 背包问题升级版 回溯算法 动态规划-二维...

网友评论

      本文标题:动态规划-背包问题(1)-01背包

      本文链接:https://www.haomeiwen.com/subject/bsqcgltx.html