混合背包问题
来源:互联网 发布:笑傲江湖ol 知乎 编辑:程序博客网 时间:2024/06/05 20:14
/*Name: 混合背包问题 Copyright: Author: Date: 28-07-17 15:11Description: 混合背包问题 :在n种物品中选取若干件放在容量为c的背包里,分别用P[i]和W[i]存储第i种物品的价值和重量。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)求解怎么装物品可使背包里物品总价值最大。输入第一行2个数n和c,表示共有n种物品,背包总容量为c 接下来n行,每行3个数Wi,Pi和Ni,分别表示第i种物品的重量,价值和最大数量(若Ni=0,则表示此物品可取无限次) 输出一个整数,表示背包里物品最大总价值样例输入3 102 1 03 3 14 5 4样例输出11算法分析:考虑到0-1背包是多重背包问题的一个特例,所以混合背包问题可以分为完全背包和多重背包两种情况分析。只需要判断Ni的值,然后分别使用完全背包和多重背包的算法来写代码就行了。我们可以二维数组记录最优解,也可以进行降维优化,使用一维数组记录最优解。 */#include<iostream>#include<cmath>using namespace std;const int MAXC = 6000; //背包最大容量 const int MAXN = 2000; //物品的个数int W[MAXN+1];//物品的重量 int P[MAXN+1];//物品的价值 int N[MAXN+1];//物品的最大数量 int B[MAXN+1][MAXC+1]; //记录给定n个物品装入容量为c的背包的最大价值int F[MAXC+1]; //记录装入容量为c的背包的最大价值int MixPack_1(int n, int c);//混合背包问题:二维数组记录最优解int MixPack_2(int n, int c);//混合背包问题:一维数组记录最优解int main() {int n, c;cin >> n >> c;for (int i=1; i<=n; i++)//不计下标为0的元素 {cin >> W[i] >> P[i] >> N[i];}cout << MixPack_1(n, c) << endl;cout << MixPack_2(n, c) << endl;return 0;}int MixPack_1(int n, int c)//混合背包问题:二维数组记录最优解{for (int i=1; i<=n; i++){if (N[i] == 0) //完全背包{ for (int j=1; j<=c; j++){if (j < W[i]) //容量不够,则和给定i-1个物品装入容量为j的背包的结果一致 {B[i][j] = B[i-1][j];}else //B[i][j-W[i]]表示给定i个物品装入容量为j-W[i]的背包,质量为W[i]的物品可能装了多个 {B[i][j] = max(B[i-1][j], B[i][j-W[i]] + P[i]);}}}else //多重背包(包含0-1背包) {for (int k=0; k<N[i]; k++)//对第i种物品进行N[i]次0-1选择 {for (int j=c; j>0; j--) //0-1背包问题,j只能递减,注意与完全背包问题的区别 {if (j < W[i]) //容量不够,则和给定i-1个物品装入容量为j的背包的结果一致 {B[i][j] = B[i-1][j];}else //B[i][j-W[i]]表示给定i个物品装入容量为j-W[i]的背包,质量为W[i]的物品可能已经装了多个 {B[i][j] = max(B[i-1][j], B[i][j-W[i]] + P[i]);}} } }}return B[n][c];}int MixPack_2(int n, int c)//混合背包问题:一维数组记录最优解{for (int i=1; i<=n; i++){if (N[i] == 0) //完全背包{ for (int j=W[i]; j<=c; j++){//当(j < W[i] || F[j] > F[j-W[i]] + P[i])时,F[j]的值不变if (F[j] < F[j-W[i]] + P[i])F[j] = F[j-W[i]] + P[i];}}else //多重背包(包含0-1背包) {for (int k=0; k<N[i]; k++)//对第i种物品进行N[i]次0-1选择 {//须先求出列坐标j较大的元素,故让循环变量j的值从大到小递减for (int j=c; j>=W[i]; j--){//当(j < W[i] || F[j] > F[j-W[i]] + P[i])时,F[j]的值不变if (F[j] < F[j-W[i]] + P[i])F[j] = F[j-W[i]] + P[i];}}}}return F[c];}
阅读全文
0 0
- 混合背包问题
- 混合背包问题
- hdu 3535(混合背包问题)
- 混合背包问题(四)
- 混合三种背包问题
- 背包九讲之混合背包问题
- 背包问题——01背包、完全背包、多重背包、混合三种背包问题
- 背包问题(1)——01背包、完全背包、多重背包、混合三种背包问题
- P04: 混合三种背包问题
- P04: 混合三种背包问题
- P04: 混合三种背包问题
- P04: 混合三种背包问题
- 混合三种背包问题c++
- P04: 混合三种背包问题
- P04: 混合三种背包问题
- 背包问题教程-01背包,完全背包,多重背包,混合背包
- 背包问题之0/1背包,完全背包,多重背包,混合背包
- 背包问题教程-01背包,完全背包,多重背包,混合背包 收藏
- 北京大学前言交叉学科研究院大数据中心夏令营和信科夏令营心得
- 菜鸟与 cef 的邂逅之旅(一):cef 源码获取与编译
- ROS学习笔记(一)
- C++——NOIP2016普及组 t4——魔法阵
- js 显示 emoji 表情
- 混合背包问题
- MFC 各个窗口 控件的风格等
- configure: error: Cannot find libmysqlclient under /usr
- 如何解决sql注入的问题
- [组合数]求组合数的几种方法总结
- 简单的思维导图怎么画
- Mybatis开端
- 使用Python和Flask编写Prometheus监控
- Ubuntu开机报错:could not update ICEauthority file /home/user/.ICEauthority