相信很多小伙伴刷题的时候面对力扣上近两千道题目,感觉无从下手,我花费半年时间整理了Github项目:leetcode刷题攻略。 里面有100多道经典算法题目刷题顺序、配有40w字的详细图解,常用算法模板总结,以及难点视频讲解,按照list一道一道刷就可以了!star支持一波吧!

之前我们已经体统的讲解了01背包和完全背包,如果没有看过的录友,建议先把如下三篇文章仔细阅读一波。

  • 动态规划:关于01背包问题,你该了解这些!
  • 动态规划:关于01背包问题,你该了解这些!(滚动数组)
  • 动态规划:关于完全背包,你该了解这些!

这次我们再来说一说多重背包

多重背包

对于多重背包,我在力扣上还没发现对应的题目,所以这里就做一下简单介绍,大家大概了解一下。

有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大。

多重背包和01背包是非常像的, 为什么和01背包像呢?

每件物品最多有Mi件可用,把Mi件摊开,其实就是一个01背包问题了。

例如:

背包最大重量为10。

物品为:

重量 价值 数量
物品0 1 15 2
物品1 3 20 3
物品2 4 30 2

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

和如下情况有区别么?

重量 价值 数量
物品0 1 15 1
物品0 1 15 1
物品1 3 20 1
物品1 3 20 1
物品1 3 20 1
物品2 4 30 1
物品2 4 30 1

毫无区别,这就转成了一个01背包问题了,且每个物品只用一次。

这种方式来实现多重背包的代码如下:

void test_multi_pack() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};vector<int> nums = {2, 3, 2};int bagWeight = 10;for (int i = 0; i < nums.size(); i++) {while (nums[i] > 1) { // nums[i]保留到1,把其他物品都展开weight.push_back(weight[i]);value.push_back(value[i]);nums[i]--;}}vector<int> dp(bagWeight + 1, 0);for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}for (int j = 0; j <= bagWeight; j++) {cout << dp[j] << " ";}cout << endl;}cout << dp[bagWeight] << endl;}
int main() {test_multi_pack();
}
  • 时间复杂度:O(m * n * k) m:物品种类个数,n背包容量,k单类物品数量

也有另一种实现方式,就是把每种商品遍历的个数放在01背包里面在遍历一遍。

代码如下:(详看注释)

void test_multi_pack() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};vector<int> nums = {2, 3, 2};int bagWeight = 10;vector<int> dp(bagWeight + 1, 0);for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量// 以上为01背包,然后加一个遍历个数for (int k = 1; k <= nums[i] && (j - k * weight[i]) >= 0; k++) { // 遍历个数dp[j] = max(dp[j], dp[j - k * weight[i]] + k * value[i]);}}// 打印一下dp数组for (int j = 0; j <= bagWeight; j++) {cout << dp[j] << " ";}cout << endl;}cout << dp[bagWeight] << endl;
}
int main() {test_multi_pack();
}
  • 时间复杂度:O(m * n * k) m:物品种类个数,n背包容量,k单类物品数量

从代码里可以看出是01背包里面在加一个for循环遍历一个每种商品的数量。 和01背包还是如出一辙的。

当然还有那种二进制优化的方法,其实就是把每种物品的数量,打包成一个个独立的包。

和以上在循环遍历上有所不同,因为是分拆为各个包最后可以组成一个完整背包,具体原理我就不做过多解释了,大家了解一下就行,面试的话基本不会考完这个深度了,感兴趣可以自己深入研究一波。

总结

多重背包在面试中基本不会出现,力扣上也没有对应的题目,大家对多重背包的掌握程度知道它是一种01背包,并能在01背包的基础上写出对应代码就可以了。

至于背包九讲里面还有混合背包,二维费用背包,分组背包等等这些,大家感兴趣可以自己去学习学习,这里也不做介绍了,面试也不会考。

我是程序员Carl,可以找我组队刷题,也可以在B站上找到我,关注公众号代码随想录来和上万录友一起打卡学习算法,来看看,你会发现相见恨晚!

如果感觉对你有帮助,不要吝啬给一个

「代码随想录」关于多重背包,你该了解这些!相关推荐

  1. 新功能又来啦!这次是「代码搜索」和视频直播!

    不知不觉又到周五,菌菌又带着新功能来啦! 代码搜索功能发布,提升开发效率 开发一个项目,配置参数是必不可少的步骤,而项目规模越大需要配置的参数就越多.怎么样?是不是已经开始头疼了?dengdengde ...

  2. 如何排版 微信公众号「代码块」之 MarkEditor

    前段时间写过一篇文章 如何排版微信公众号「代码块」,讲的是如何使用浏览器插件 Markdown Here 来排版代码块.虽然用 Markdown Here 排版出来的样式还不错,但存在一个问题,就是代 ...

  3. 「代码家」的学习过程和学习经验分享【转】

    图灵丛书的一句话说的很好,Standing on the shoulders of giants,是的,我们一直站在巨人的肩上,我们起步都在沿着他们的轨迹前行,之后慢慢的在前人的开发基础或者规范上写出 ...

  4. 如何排版 微信公众号「代码块」

    最近博主刚开通微信公众号「石佳劼的博客」,被微信公众平台的图文编辑器折腾的不轻,如果文章中包含「代码块」,怎么排版都显得杂乱无章.之前一直用 Markdown 写作,从来没有考虑过排版.样式问题,因为 ...

  5. 「代码家」的学习过程和学习经验分享

    每天,都会有人在微博上私信我,问我关于学习和成长的问题.这种问题我一般都不会回复某个j,毕竟每个人的情况不一样,每个人对待事物的性格也不一样,我不能夸下海口的说,你看某本书几个月就能如何如何,我能做的 ...

  6. 「代码家」的学习过程和学习经验分享(挺好的一篇文章,转载侵删)

    转自:https://kb.cnblogs.com/page/554260/ 感悟:多写多练,抓住灵感. 每天,都会有人在微博上私信我,问我关于学习和成长的问题.这种问题我一般都不会回复某个j,毕竟每 ...

  7. 面试题目_经典面试题目「回溯算法」解数独

    解数独,理解二维递归是关键! 通知:我将公众号文章和学习相关的资料整理到了Github :https://github.com/youngyangyang04/leetcode-master,方便大家 ...

  8. 代码随想录【Day 30】| 332.重新安排行程 、51. N皇后 、37. 解数独

    代码随想录[Day 30] | 332.重新安排行程 .51. N皇后 .37. 解数独 332.重新安排行程 题目链接:332.重新安排行程 卡尔文解 解题思路及注意事项: 代码实现: 51. N皇 ...

  9. 用 Electron 打造 Win/Mac 应用,从「代码」到可下载的「安装包」,可能比你想得麻烦一点...

    首发于酷家乐前端博客,作者@摘星(segmentfault @StinsonZhao) 我们能从很多地方学习到怎么起一个 Electron 项目,有些还会介绍怎么打包或构建你的代码,但距离「真正地发行 ...

  10. 用 Electron 打造 Win/Mac 应用,从「代码」到可下载的「安装包」,可能比你想得麻烦一点... 1

    2019独角兽企业重金招聘Python工程师标准>>> 首发于酷家乐前端博客 我们能从很多地方学习到怎么起一个 Electron 项目,有些还会介绍怎么打包或构建你的代码,但距离「真 ...

最新文章

  1. oracle 使用nfs挂载的目录不能进行归档
  2. 公司又有人被开除了,这次真的是...
  3. the worries in life: basically two things
  4. android: 播放音频
  5. $.ajax()方法详解(网上引用)
  6. PNG免扣(抠)素材,直接应用才是设计师友好的帮助图片
  7. 《跟我一起做J2EE版Blog–jPress》4(搭建marven下的Spring和Hibernate)
  8. 信息学奥赛一本通(C++版)在线评测系统 1205:汉诺塔问题
  9. 【SpringBoot】1、创建第一个SpringBoot项目
  10. 速率法和终点法的区别_两点法、终点法、速率法
  11. 打开html文件是文字模式,为什么我打开的有些网页成了全文字格式的?
  12. 如何打造以人为本的移动游戏
  13. obs-studio 二次封装 (四)obs 音视频采集到推流大体流程图
  14. html5页面拨打电话,5.添加页面/设置点击拨打电话
  15. 网站TDK的设置方法-怎么合理的设置网站的TDK
  16. XBee模块实现QGC与PX4飞控的组网通信连接
  17. Telnet服务配置
  18. 导入EXCEL表时,提示找不到可安装的ISAM怎么办
  19. Autosar MCAL-GTM之TOM
  20. 轻松可视化实现设备监控大屏效果

热门文章

  1. coursera 《现代操作系统》 -- 第八周 存储模型(2)
  2. BZOJ 4766: 文艺计算姬 [矩阵树定理 快速乘]
  3. [如何构建自己的轮式移动机器人系统·从入门到放弃]机器人底层篇
  4. flask开发restful api系列(7)-蓝图与项目结构
  5. 课堂随笔01--进制转换
  6. 再谈new functionName
  7. Discuz! 7.2 二次开发基础 (一)
  8. cmd使用conda建立python虚拟环境
  9. 封装特效记录--持续更新
  10. CSS3实现轮播图效果