问题描述:
给定n种物品和一个背包。物品i的重量为w[i],其价值为v[i],背包的容量为c。应如何选择装入 背包的物品,使得装入背包中的物品的总价值最大。每种物品最多装入一次。
0-1背包问题:对于要装入背包中的物品,只有两种选择:全部装入或者不装入。
背包问题:对于要装入背包中的物品,可以选择装入一部分,不一定要全部装入背包中。
算法分析:
使用贪心策略求解此类问题时,首先要选出最优的度量标准。
可供选择的度量标准有三种:价值,容量,单位价值(v/w,价值/重量)。
最优的度量标准是单位价值。
背包问题算法思路:
1、将各个物品按照单位价值由高到低排序;
2、取价值最高者放入背包;
3、计算背包的剩余空间;
4、重复2-3步,直到背包剩余容量=0或者物品全部装入背包为止(对于0-1背包,终止条件为背包剩余容量无法装入任意一件物品或者物品全部装入背包)。
#include<iostream>
using namespace std;
/*
* 背包问题
* n:物品个数
* c:背包容量
* v[]:每个物品的价值
* w[]:每个物品的重量(这里已经按照单位价值降序排列 )
* x[]:物品是否放入背包(0表示不放,1表示全部放入,0-1放入一部分)
*/
void package(int n,float c,float v[],float w[],float x[]){
int i;
for(i=0;i<n;i++){
x[i]=0;
}
for(i=0;i<n;i++){
if(w[i]>c)
break;
x[i]=1;
c=c-w[i];
cout<<"放入第"<<i+1<<"件物品,背包剩余容量" <<c<<endl;
}
if(i<=n){
x[i]=c/w[i];
printf("放入第%d件物品的%f部分.背包剩余容量为0.\n",(i+1),w[i]*x[i]);
}
}
/*
* 0-1背包问题
* n:物品个数
* c:背包容量
* v[]:每个物品的价值
* w[]:每个物品的重量(这里已经按照单位价值降序排列 )
* x[]:物品是否放入背包(0表示不放,1表示全部放入)
*/
void package0_1(int n,float c,float v[],float w[],float x[]){
int i;
for(i=0;i<n;i++)
x[i]=0;
for(i=0;i<n;i++){
if(w[i]>c)
break;
x[i]=1;
c=c-w[i];
printf("放入第%d件物品,背包剩余容量%f.\n",(i+1),c);
}
}
int main(){
int n=3;
float c=20;
float v[]={24,15,25};
float w[]={15,10,18};//已经按照单位价值降序排列
float *x;
cout<<"******背包*******"<<endl;
x = (float*)malloc(sizeof(float)*n);
package(n,c,v,w,x);
cout<<"******0_1背包*******"<<endl;
package0_1(n,c,v,w,x);
}