美文网首页
动态规划完全背包01

动态规划完全背包01

作者: 分布式与微服务 | 来源:发表于2022-11-07 09:07 被阅读0次

完全背包

和01背包一样力扣上没有没有纯完全背包问题,都是需要完全背包的各种应⽤,需要转化成完全背包问题,所以我们这⾥还是以纯完全背包问题来讨论其理论和原理。
有N件物品和⼀个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有⽆限个(也就是可以放⼊背包多次),求解将哪些物品装⼊背包⾥物品价值总和最⼤。 完全背包和01背包问题唯⼀不同的地⽅就是,每种物品有⽆限件。
题:背包最⼤重量为4。
物品为:


问背包能背的物品最⼤价值是多少?

因为01背包和完全背包唯⼀不同就是体现在遍历顺序上,所以本⽂就不去做动规五部曲了,我们直接针对遍历顺序经⾏分析!
⾸先在回顾⼀下01背包遍历顺序的核⼼代码:

        for (int i = 0; i < weight.length; i++) {//遍历物品
            for (int j = bagWeight; j >= weight[i]; j--) {背包容量
                    dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
            }
        }

我们知道01背包内嵌的循环是从⼤到⼩遍历,为了保证每个物品仅被添加⼀次。
⽽完全背包的物品是可以添加多次的,所以可以而且需要从⼩到⼤去遍历,即:

        for (int i = 0; i < weight.length; i++) {//遍历物品
            for (int j = weight[i]; j < bagWeight; j++) {背包容量
                    dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
            }
        }

dp状态图如下:


到这里就可以进行解题了,其实还有⼀个很重要的问题,为什么遍历物品在外层循环,遍历背包容量在内层循环?
这个问题很多地方关于这⾥都是轻描淡写就略过了,⼤家都默认 遍历物品在外层,遍历背包容量在内层,好像本应该如此⼀样,那么为什么呢?难道就不能遍历背包容量在外层,遍历物品在内层?
在之前01背包问题的文章中我们就提到过很多次。01背包中⼆维dp数组的两个for遍历的先后循序是可以颠倒了,一维dp数组的两个for循环先后循序⼀定是先遍历物品,再遍历背包容量。就是为了防止重复放入物品,而在完全背包中应为物品可以是无限次使用,所以对于⼀维dp数组来说,其实两个for循环嵌套顺序同样⽆所谓!而且在完全背包中dp[j] 是根据 下标j之前所对应的dp[j]计算出来的。 只要保证下标j之前的dp[j]都是经过计算的就可以了。遍历物品在外层循环,遍历背包容量在内层循环,状态如图:


遍历背包容量在外层循环,遍历物品在内层循环,状态如图:

看了这两个图,⼤家就会理解,完全背包中,两个for循环的先后循序,都不影响计算dp[j]所需要的值(这个值就是下标j之前所对应的dp[j])。
先遍历被背包在遍历物品,Java代码如下:

for (int i = 0; i <= bagWeight; i++)
    for (int j = 0; j < weight.length; j++)
        if (i >= weight[j])
            dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);

完整先遍历物品再遍历背包,Java代码如下:

    public int dp(int[] weight, int[] value, int bagWeight){
        int[] dp = new int[bagWeight + 1];
        for (int i = 0; i < weight.length; i++)
            for (int j = weight[i]; j <= bagWeight; j++)
                dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
        return  dp[bagWeight];
}

完整先遍历背包再遍历物品,Java代码如下:

public int dp(int[] weight, int[] value, int bagWeight){
    int[] dp = new int[bagWeight + 1];
    for (int i = 0; i <= bagWeight; i++)
        for (int j = 0; j < weight.length; j++)
            if (i >= weight[j])
                dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
    return  dp[bagWeight];
}

相关文章

  • 动态规划完全背包01

    完全背包 和01背包一样力扣上没有没有纯完全背包问题,都是需要完全背包的各种应⽤,需要转化成完全背包问题,所以我们...

  • 算法学习收藏

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

  • 动态规划之01背包和完全背包

    01背包问题(注意看注释) 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。每种物品仅...

  • 背包入门

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

  • 动态规划之背包问题(01背包,完全背包,多重背包)

    01背包 问题描述 有N个物品,每个物品的重量为weight[i],每个物品的价值为value[i]。现在有一个背...

  • 动态规划-02完全背包

    问题描述 有n个物品,它们有各自的体积和价值,现有给定容量V的背包,每种物品都就可以选择任意数量,如何让背包里装入...

  • 剑指 Offer II 103. 最少的硬币数目

    动态规划。完全背包 二维数组 转一维数组

  • 动态规划-01背包

    问题描述 有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?为方便...

  • 背包问题(01背包+leetcode416)

    动态规划合集: 1.矩阵链乘法2.投资组合问题3.完全背包问题4.01背包问题5.最长公共子序列 例题4——01背...

  • 经典动态规划:完全背包问题

    读完本文,你可以去力扣拿下如下题目: 518.零钱兑换II[https://leetcode-cn.com/pro...

网友评论

      本文标题:动态规划完全背包01

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