关于完全背包的解析以及完全背包与01背包的区别及代码

这篇具有很好参考价值的文章主要介绍了关于完全背包的解析以及完全背包与01背包的区别及代码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

完全背包是什么呢?如果大家了解过01背包那么完全背包也是可以理解的。完全背包也是求一个固定容量的背包,能够装入物品的最大价值是多少,也就是说该背包最多能装多少价值?和01背包不同的是,完全背包里所能装的各个物品给定是无限的,也就是说同一个物品我们可以取很多次。

这就是它们的题目区别,这一点区别对于遍历顺序来说影响巨大,我们这次用一维数组来解决完全背包的问题。

关于一维数组解决思路如果有不明白的地方,可以去看我以前发过的01背包的一维数组解决思路。

完全背包一维数组解决的动规五部曲中,dp数组的含义,递推公式,dp数组的初始化与01背包的一维数组解决思路前三步完全相同,这里不再做过多描述。我们重点讲解完全背包的遍历顺序是怎样的。

完全背包的遍历顺序,对于背包遍历顺序不再和01背包相同了,01背包的遍历顺序是从后向前,这是由于我们递推公式特性决定的,它会和之前的容量价值相对比,为了使背包中每个物品都只能用一次,所以我们只能用倒序的遍历,而完全背包物品可以用无数次,所以我们要遍历背包时候,正序遍历。这样第一次遍历其他容量的背包就有数,大容量背包在第一次填数时候就可以和之前小容量背包比较价值,使背包加入更多同样物品,进而使背包价值更大。这里的背包遍历顺序是由物品的数目不同而引起的变化。

那么完全背包的两层fou循环可以颠倒吗?也就是说我们可以先遍历背包再遍历物品吗?答案是纯完全背包的问题是可以的!两个for循环颠倒顺序没有什么影响。没错,即使是用一维数组实现完全背包,它仍然不受影响,完全背包的各部分数据也就是背包价值,是由上一次的填数所推出的,即使先锁定背包容量,往里面持续填各种物品也是可以的,因为物品数目没有限制的缘故,并不会发生类似于01背包锁定背包容量时,出现的背包只能装入一个物品的bug!锁定背包容量,也就是背包容量遍历在第一个for循环,也就是外部循环,它遍历完之后并不会再遍历了,如果是01背包由于它的背包遍历还是倒着遍历的,以至于在放后面的物品时候,根据递推公式我们要腾出地方dp【j-weight【i】】这个时候前面的小容量背包暂时没有值,导致背包虽有空间但却无法放入其他物品!!!这也是为什么01背包不能够颠倒for循环,可能以前的那个章节我对这里的解释并不是很清晰,大家可以看这里好好理解。01背包之所以不能够颠倒for循环,和递推公式、物品的数量限制、01背包的本身遍历背包的顺序是有着不可分割的关系的。

我们上面提到了,下一步我们要填的数是和上一次的值推出来的,我们可以分别画表格,无论是哪一个先遍历,都不会影响完全背包的背包价值,因为它是正向遍历背包且物品可以放很多个,这样在放其他物品时候和上一次放很多个上一个物品时候,取最大值是不受for循环颠倒所干扰的。

实际上这些事情在我第一次学习01背包的时候并不能很好的理解,为什么01背包用一维数组实现不能for循环倒置,那个时候还有想过,如果倒置了之后背包不倒序遍历呢?其实和这个没有干系,背包的倒序遍历,是控制物品个数的!我们要搞清楚哪一步都是用来做什么的,这样才能更深刻的理解解题思路。理论的解释可能有时候显得确实差一点意思,感觉不到到底是究竟为什么完全背包就不受for循环颠倒所影响,最好还是通过对代码的调试来理解,到底是否存在着干扰。

给出代码文章来源地址https://www.toymoban.com/news/detail-408316.html

// 先遍历物品,在遍历背包
void test_CompletePack() {
    vector<int> weight = {1, 3, 4};
    vector<int> value = {15, 20, 30};
    int bagWeight = 4;
    vector<int> dp(bagWeight + 1, 0);
    for(int i = 0; i < weight.size(); i++) { // 遍历物品
        for(int j = weight[i]; j <= bagWeight; j++) { // 遍历背包容量
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
        }
    }
    cout << dp[bagWeight] << endl;
}
int main() {
    test_CompletePack();
}

// 先遍历背包,再遍历物品
void test_CompletePack() {
    vector<int> weight = {1, 3, 4};
    vector<int> value = {15, 20, 30};
    int bagWeight = 4;

    vector<int> dp(bagWeight + 1, 0);

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

到了这里,关于关于完全背包的解析以及完全背包与01背包的区别及代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

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

    目录 01背包模型 题目  dp   滚动数组优化 第一问  第二问  扩展 完全背包 题目  动态规划​编辑  滚动数组优化  关于-1的代码层面优化 💰🪙 背包就是有限制条件的组合问题 有一个背包能容纳的体积是v,现在有n个物品,第i个物品的体积为vi,价值为wi。 (1)求这个背包

    2024年01月20日
    浏览(32)
  • 【笔记】动态规划(1)---01背包和完全背包

    集合:选法集合 属性:最优选择 集合的划分 状态表示 集合:所有只考虑 第i个物品前的 且总体积不大于j的所有 选法 。 属性:在所有集和中, 价值最大的选法 。 状态计算 集合的划分:总是在(第 i - 1个) 状态最优时,计算 第 i 个状态。 背包已经最优,故对于任意容积

    2024年02月02日
    浏览(58)
  • 三十八、动态规划——背包问题( 01 背包 + 完全背包 + 多重背包 + 分组背包 + 优化)

    0 1 背包问题: 条件:N 个物品容量为 V 的背包,每件物品最多用 1 次,其中物品信息体积为 Vi,价值为 Wi。 目标:选出物品,使价值最大(不一定装满背包)。 特点:每件物品 最多只用 1 次 完全背包问题: 特点:每一件物品都有 无限个 多重背包问题: 特点:每个物品

    2024年02月07日
    浏览(37)
  • 算法竞赛必考算法——动态规划(01背包和完全背包)

    1.1题目介绍 1.2思路一介绍(二维数组) 代码如下: 1.3思路二介绍(一维数组) 空间优化   为什么可以使用一维数组?   我们先来看一看01背包问题的状态转移方程,我们可以发现 f[i]只用到了f[i-1],其他的是没有用到的,我们可以用滚动数组来做。   还有一个原因就是我

    2024年02月02日
    浏览(36)
  • 算法套路十四——动态规划之背包问题:01背包、完全背包及各种变形

    如果对递归、记忆化搜索及动态规划的概念与关系不太理解,可以前往阅读算法套路十三——动态规划DP入门 背包DP介绍:https://oi-wiki.org/dp/knapsack/ 0-1背包:有n个物品,第i个物品的体积为w[i],价值为v[i],每个物品至多选一个, 求体积和不超过capacity时的最大价值和,其中i从

    2024年02月10日
    浏览(41)
  • 算法修炼之筑基篇——筑基一层中期(解决01背包,完全背包,多重背包)

    ✨ 博主: 命运之光​​​​​​ 🦄 专栏: 算法修炼之练气篇​​​​​ 🍓 专栏: 算法修炼之筑基篇 ✨ 博主的其他文章: 点击进入博主的主页​​​​​​ 前言: 学习了算法修炼之练气篇想必各位蒟蒻们的基础已经非常的扎实了,下来我们进阶到算法修炼之筑基篇的

    2024年02月08日
    浏览(23)
  • 代码随想录 day44 完全背包

    class Solution { public:     int change(int amount, vectorint coins) {         vector int dp(amount+1,0);         dp[0]=1;         for(int i=0;icoins.size();i++){             for(int j=coins[i];j=amount;j++){                 dp[j]+=dp[j-coins[i]];             }         }  

    2024年02月15日
    浏览(33)
  • 动态规划:0-1背包、完全背包问题 | 详细原理解释 | 代码及优化(C++)

    目录 01背包 问题描述: 简单描述就是: 解析: 递推公式: dp数组的初始化: 遍历顺序: 图解: 实现代码: dp数组初始化: 遍历: 优化: 原理: 递推公式: 遍历顺序: 实现代码: 初始化: 遍历: 完全背包 问题描述: 解析: 实现代码:         01背包是在M件物品

    2024年02月11日
    浏览(28)
  • 01背包问题----动态规划 -----python代码、优化

    问题描述: 容量为C的背包选择装物品,有n个物品,它们有各自的体积wi和价值vi,如何让背包里装入的物品具有最大价值? 解题思路: 也就是n个物品选择装入背包,每个物品都有两种选择,是(1)或否(0), 建模:       xi表示当前第i个物品是否选择,xi取值为(0,1)

    2024年02月04日
    浏览(42)
  • 【第二十五课】动态规划:完全背包问题(acwing-3 / 公式推导 / 思路理解 / 优化 / c++代码)

    目录 思路 朴素代码 优化 公式推导上  二维代码  一维代码 公式理解上   在开始看完全背包问题之前,可能需要先了解01背包及其解决办法。 指路👇 【第二十五课】动态规划:01背包问题(acwing-2 / 思路 / 含一维数组优化 / c++代码) 这个问题和01背包的区别就是 每件物品可以

    2024年03月19日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包