在这之前,我们讲到了01背包与完全背包。这次,我们来讲一讲很搞笑又稀奇古怪的(我不认为)多重背包问题。

多重背包问题

经典例题

例【n+2】这位流浪的探险者被困在了海岛上。有一天,他发现了一艘船,于是,他就乘坐这艘船准备回家。这时,他在岛上获取了N种东西,每件物品有n件真古怪哈,价值c,费用w,他需要让带回去的东西有更大的价值,所以,编程帮助他,找出最佳搭配。

感觉大家已经能够猜出这个悲催的人是谁了,就是大名鼎鼎的——鲁滨孙大人!!!

基本思路

这个题目不用说了吧,很简单,和完全背包基本一样。现在,我们只要把完全背包的方程略微改动即可。这种背包问题对于每种物品有n[i]+1(此处n为最多取物品的数量)种策略:取0个,1个,…n[i]个。令f[i][v]表示前i种物品恰放入容量为v的最大价值,则得出动态转移方程:
f(i)(v)=max(f(i−1)(v),f(i−1)(v−k∗w(i))+k∗c(i)∣0<=k<=n(i))f(i)(v)=max(f(i-1)(v),f(i-1)(v-k*w(i))+k*c(i)|0<=k<=n(i)) f(i)(v)=max(f(i−1)(v),f(i−1)(v−k∗w(i))+k∗c(i)∣0<=k<=n(i))此种算法时间复杂度为O(V∗∑n(i))O(V*∑n(i))O(V∗∑n(i))。
结论得出的伪代码如下:

for(i=1...n)for(v=V...0)               //此地根据01写出,由于与完全不同,所以是V...0for(k=0...n[i]){if(v-k*v[i]<0) break;           //在for之前无法判断,只好在这里f[i][v]=max(f[i-1][v],f[i-1][v-k*w[i]]+k*c[i]);}

换一种好想好写的分析方法,将多重背包转换为01背包问题:把第i种物品换成n[i]件01背包中的物品,则得到了物品数为(∑n(i))(∑n(i))(∑n(i))的01背包问题,直接求解,时间复杂度依然是(O(V∗∑n(i)))(O(V*∑n(i)))(O(V∗∑n(i)))。

但是,我们要做一个懒人 勤快之人,期望将他转换成01背包问题之后就像上次完全背包问题一样降低复杂度。仍然考虑二进制的思想,把第i件物品换成若干件物品,使原问题中第i中物品可以取用的每种策略(取0~n[i]件物品)是与若干件物品代换后的相同。注意,取超过n[i]件物品的策略肯定不能出现。

于是,方法出现。将第i种物品换成n[i]件相同的物品,其中每件物品都有一个系数,这件物品的费用和价值均是原来的费用与价值乘上这个系数,使这些系数分别为1,2,4,···,2k−12^{k-1}2k−1,n(i)−2k+1n(i)-2^k+1n(i)−2k+1,且k是满足n(i)−2k+1>0n(i)-2^k+1>0n(i)−2k+1>0的最大整数(这里请注意,分出的数是可以组合出n[i]内所有数字)。

是不是感觉蒙了!炸了!
好,我们来举一个例子就可以明白了。总结上面的方法,假设n[i]=13,就将这种物品分成系数分别为1,2,4,6的四件物品(分成了四件一样但意义不同的物品,如果试试看,你就会发现,1,2,4,6可以组成13以内的任何数字。1,2,1+2,4,1+4,6,1+6,2+6,1+2+6,4+6,1+4+6,2+4+6,1+2+4+6=13)

对于上面有趣的式子,可以分0…2k−12^{k-1}2k−1和2k2^k2k…2n[i]讨论得出,希望读者自己思考思考,开动脑筋。

分成的这些物品系数的和为n[i],表示不可能取多于n[i]的第i件物品。这样就将第i件物品分为了log∗n(i)log*n(i)log∗n(i)种物品,将原问题的复杂度转化为O(V∗∑logn(i))O(V*∑logn(i))O(V∗∑logn(i))这是很大的改进呀!

分析结束,此处贴出慢版的程序:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int v[10000],w[10000],s[10000],f[10000],n,m,i,j,k;
int main  ()
{cin>>n>>m;for (i=1; i<=n; i++)cin>>v[i]>>w[i]>>s[i];for (i=1; i<=n; i++)for (j=m; j>=0; j--)for (k=1; k<=s[i]; k++){if (j-k*v[i]<0) break;f[j]=max(f[j-k*v[i]]+w[i]*k,f[j]);}cout<<f[m];
}

如有需要快版程序,请下载附带的资源包或发私信给我。


写文章不易,请大家多多支持,谢谢。

【C++背包】稀奇古怪的多重背包问题相关推荐

  1. 01背包、完全背包、多重背包问题的C++实现及路径记录

    这里主要实现路径记录,只求最值问题移步 01背包.完全背包.多重背包问题的C++实现 以下均打印输出路径,即装入背包的物品序号,和最大值. 01背包问题 #include <iostream&g ...

  2. 01背包、完全背包、多重背包问题的C++实现

    01背包问题 容量为10的背包,有5种物品,每种物品只有一个,其重量分别为5,4,3,2,1,其价值分别为1,2,3,4,5. 设计算法,实现背包内物品价值最大. 代码如下(输出14) #includ ...

  3. java多重背包算法,【动态规划】多重背包问题

    说明 前面已经介绍完了01背包和完全背包,今天介绍最后一种背包问题--多重背包. 这个背包,听起来就很麻烦的样子.别慌,只要你理解了前面的两种背包问题,拿下多重背包简直小菜一碟. 如果没有看过前两篇0 ...

  4. 背包问题-【01背包】【完全背包】【多重背包】【多限定条件背包】

    背包问题 给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高. 可参考https://www.cnblogs.com/-guz/p/9866118.h ...

  5. python多重背包_【动态规划】多重背包问题

    说明 前面已经介绍完了01背包和完全背包,今天介绍最后一种背包问题--多重背包. 这个背包,听起来就很麻烦的样子.别慌,只要你理解了前面的两种背包问题,拿下多重背包简直小菜一碟. 如果没有看过前两篇0 ...

  6. python多重背包问题_01-背包、完全背包、多重背包及其相关应用

    本文介绍了背包问题系列,主要包括: [1] 01-背包及其应用 [2]完全背包及其应用 [3]多重背包 [1]01-背包及其应用: 1.1.01-背包问题描述: 有 N 件物品和一个容量为 C 的背包 ...

  7. python多重背包_多重背包问题(python实现),动态规划

    多重背包问题 感谢这些朋友们的文章,给了我很大启发: https://blog.csdn.net/songyunli1111/article/details/94778914 https://blog ...

  8. c++ 多重背包状态转移方程_背包问题之零钱兑换

    读完本文,你可以去力扣拿下如下题目: 518.零钱兑换II ----------- 零钱兑换 2 是另一种典型背包问题的变体,我们前文已经讲了 经典动态规划:0-1 背包问题 和 背包问题变体:相等子 ...

  9. P03: 多重背包问题

    P03: 多重背包问题 题目 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和 ...

  10. 多维多重背包问题_满满干货!背包问题全总结(带c++源码)

    目录: 动态规划简介 0-1 背包问题 完全背包问题 多重背包问题 混合背包问题 二维(多维)费用背包问题 分组的背包问题 有依赖的背包问题 动态规划简介 在学习背包问题之前需要对动态规划有一定的了解 ...

最新文章

  1. 程序设计分析(开篇)——混沌初开,顿悟设计
  2. 布兰森:激励是最好的加速器
  3. jQuery获取元素
  4. 配置redis三主三从
  5. 定义jQuery插件
  6. Nginx 配置TCP和UDP负载均衡
  7. 图片变色_一张图看懂手机CMF史,附带手机渐变色工艺解析
  8. 华南师范大学计算机学院报录比,2020华南师范大学考研报录比.docx
  9. centos 6.2   为mysql5.6.10安装 HandlerSocket插件
  10. 小D课堂 - 新版本微服务springcloud+Docker教程_5-01分布式核心知识之熔断、降级
  11. 项目长期运维中产生的一些问题
  12. c语言函数调用原理底层分析
  13. matlab cholesky分解函数,matlab中矩阵LDLT分解与Cholesky分解
  14. 关于Unity资源包导入项目后版本不匹配问题
  15. python 爬取google总结
  16. linux用户motd,linux需要装?那就和我一起来配置一个动态的MOTD登陆效果吧
  17. 毫米和像素怎么换算_图片的像素和毫米之间的换算关系
  18. OSPF虚链接的基本配置
  19. 机器学习实战一:泰坦尼克号生存预测 Titantic
  20. (C++)编写一个判别素数的函数,在主函数输入一个整数,输出是否为素数的信息

热门文章

  1. blog11 Sent2Vec和Doc2Vec预训练模型
  2. java俄罗斯方块旋转_java俄罗斯方块旋转算法,求解
  3. linux超市参数,TI AM5708开发板产品参数介绍
  4. python绘制彩色地震剖面断层解释_断层在地震剖面上的反映及解释
  5. 教师资格证上传照片时显示“内部服务器错误”解决方法(亲测有效)
  6. 磊科linux无线网卡驱动安装步骤,无线网卡驱动安装方法
  7. 普通话和英语发音_incomplete
  8. Invenio 数字图书馆框架
  9. R语言一步到位求数据的均值,频数,标准差,标准误差
  10. 186.MultiAutoCompleteTextView