码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 完全背包问题的思路解析


    【算法分析】
    背包问题,求解的是“将
    某些种物品装入背包,......”,而不是求解“将某些个物品装入背包,......”的问题。切记。

    完全背包问题,类似于0-1背包问题,依然是求解“将
    哪些种物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大”。故依然可设 c[i][j] 为将前 i 种物品装入容量为 j 的背包中所获得的最大价值,vol[i] 为第 i 中物品的体积,val[i] 为第 i 种物品的价值。但由于其特殊性,即在完全背包问题中的每种物品有无限多个,而0-1背包问题中的每种物品只有一个,故在利用“最后一步法”构建完全背包问题的状态转移方程时,针对第 i 种物品,可能会选择0,1,2,... ,k个(k*vol[i]<=j)。之所以会选到 k 个,而不是无限多个,原因在于虽然完全背包问题中每种物品都有无限多个,但受到背包容量的限制,只可能装有限个。

    完全背包问题的视频讲解可参考:https://www.bilibili.com/video/BV16F411M7CU
    思路详见下图:

    ​​

    可见依据上图的分析思路,则完全背包问题的代码将会有三重循环,必然导致代码复杂度增加。同时,这也必然会导致时间复杂度剧增,有可能会TLE。因此,需要进行优化。

    将完全背包问题的状态转移方程写在下方: 
    c[i][j]=max(c[i-1][j],c[i-1][j-vol[i]]+val[i], ..., c[i-1][j-(k-1)*vol[i]]+(k-1)*val[i], c[i-1][j-k*vol[i]]+k*val[i]),令 j=j-vol[i],并考虑到 k*vol[i]<=j,则有
    c[i][j-vol[i]]=max(c[i-1][j-vol[i]],c[i-1][j-vol[i]-vol[i]]+val[i], ..., c[i-1][j-vol[i]-(k-1)*vol[i]]+(k-1)*val[i])
                     =max(c[i-1][j-vol[i]],c[i-1][j-2*vol[i]]+val[i], ..., c[i-1][j-k*vol[i]]+(k-1)*val[i])
    推出完全背包问题的状态转移方程 c[i][j]=max(c[i-1][j], c[i][j-vol[i]]+val[i]),这样就优化为二维了。

    类比于0-1背包问题的状态转移方程 c[i][j]=max(c[i-1][j],c[i-1][j-vol[i]]+val[i]) 优化为一维的思路,可在上面优化为二维的基础上,进一步得出完全背包问题的一维优化形式:
     c[j]=max(c[j], c[j-vol[i]]+val[i]),满足 i:1~n,j:1~V 且 j>=vol[i]

    若要从代码模板的角度来看的话,完全背包问题的代码只需要将0-1背包问题的一维实现代码的内层循环改为从 vol 到 V 进行遍历便可。即将0-1背包问题的一维实现中的内层循环 for(int j=V;j>=vol;j--) 改为 for(int j=vol;j<=V;j++) ,便为完全背包的代码实现。是不是有点废O(∩_∩)O哈哈~

    【算法代码】

    1. #include
    2. using namespace std;
    3. const int maxn=1005;
    4. int c[maxn];
    5. int main() {
    6. int n,V;
    7. cin>>n>>V;
    8. for(int i=1;i<=n;i++){
    9. int vol,val;
    10. cin>>vol>>val;
    11. for(int j=vol;j<=V;j++)
    12. c[j]=max(c[j],c[j-vol]+val);
    13. }
    14. cout<
    15. return 0;
    16. }
    17. /*
    18. in:
    19. 4 5
    20. 1 2
    21. 2 4
    22. 3 4
    23. 4 5
    24. out:
    25. 10
    26. */


    【参考文献】
    https://blog.csdn.net/hnjzsyjyj/article/details/126126183
    https://www.bilibili.com/video/BV16F411M7CU
    https://www.acwing.com/problem/content/description/3/
    https://blog.csdn.net/hnjzsyjyj/article/details/125987923


     

  • 相关阅读:
    java中流的分类
    【API篇】十一、Flink水位线传递与迟到数据处理
    【算法leetcode】2331. 计算布尔二叉树的值(多语言实现)
    免费 Copilot 用户可以访问 OpenAI 的 GPT-4 Turbo;面向 3D 虚拟环境的多面手 AI 代理
    【Python 零基础入门】变量 & 数据类型
    Python循环写文件结尾不带换行
    三个pwn题
    【数据结构:线性表——2.1 向量】
    阿里云服务器10M带宽容纳多少人同时在线?
    437-C++基础语法(81-90)
  • 原文地址:https://blog.csdn.net/hnjzsyjyj/article/details/126132364
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号