混合背包问题

来源:互联网 发布:笑傲江湖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];}