伪代码:
1、将v[i]/w[i]赋给结构体数组origData[i].data,将i记录在结构体数组origData[i].index,用来记录原始数组w[i]和v[i]下标。
2、按照origData[i].data降序排列,将数组w[]和v[]重新排列。
3、将数组x[n]初始化为0; //初始化解向量
4、i=1, vsum=0;
5、循环直到(w[i]>C)
5.1、x[i]=1; //将第i个物品放入背包
5.2、C=C-w[i];
5.3、vsum+=v[i];
5.4、 i++;
输出最优解vsum;
源代码:
#include <iostream>
#include <algorithm>
using namespace std;
struct Data
{
int data;
int index;
bool z;
};
Data origData[100];
bool cmp(Data a,Data b){
return a.data> b.data;
}
float Bag(float w[],float v[],float C,int n){
int i,x[100],vsum=0;
float r[100], w1[100], v1[100];
for(i=1; i<=n; i++)
r[i]=v[i]/w[i];
for ( i=1; i<=n; i++){
origData[i].data = r[i];
origData[i].index = i;
origData[i].z=0;
}
sort(origData+1,origData+n+1,cmp); //降序排列
for(i=1; i<=n; i++){
w1[i]=w[origData[i].index];
v1[i]=v[origData[i].index]; //改变w[],v[]数组的排列
//cout<<origData[i].index<<endl;
}
cout<<"按照单位重量价值v[i]/w[i]降序排列后的w[]数组为:";
for(i=1; i<=n; i++){
cout<<w1[i]<<" ";
}cout<<endl;
cout<<"按照单位重量价值v[i]/w[i]降序排列后的v[]数组为:";
for(i=1; i<=n; i++){
cout<<v1[i]<<" ";
}cout<<endl;
memset(x,0 , sizeof(x)); //2、初始化解向量
i=1;
while(w1[i]<=C && i<=n){
origData[origData[i].index].z=1;
C -= w1[i];
vsum +=v1[i];
i++;
}
cout<<"选择装进的物品为(1表示装入背包,0表示不装入背包):";
for(i=1; i<=n; i++)
cout<<origData[i].z<<" ";
cout<<endl;
return vsum;
}
int main()
{
int n,i,j,vsum=0;
float w[100],v[100],C;
cout<<"输入物品的数量:";
cin>>n;
cout<<"输入这"<<n<<"个物品的重量:"<<endl;
for(i=1; i<=n; i++)
cin>>w[i];
cout<<"输入这"<<n<<"个物品的价值:"<<endl;
for(j=1; j<=n; j++)
cin>>v[j];
cout<<"输入背包容量C:"<<endl;
cin>>C;
float rs=Bag(w,v,C,n);
cout<<"背包中的物品最大价值容量为:"<<rs<<endl;
return 0;
}
运行结果:
输入物品的数量:3
输入这3个物品的重量:
20 30 10
输入这3个物品的价值:
60 120 50
输入背包容量C:
50
按照单位重量价值v[i]/w[i]降序排列后的w[]数组为:10 30 20
按照单位重量价值v[i]/w[i]降序排列后的v[]数组为:50 120 60
选择装进的物品为(1表示装入背包,0表示不装入背包):0 1 1
背包中的物品最大价值容量为:170
Press any key to continue
2、动态规划法
// Note:Your choice is C++ IDE
#include <iostream>
using namespace std;
int max(int a,int b){
return a>b ? a : b;
}
//V[i][j]表示在前i个物品中能够装入容量为j的背包中的物品的价值最大值
//V[i][0] , V[0][i]都为0;
int KnapSack(int n, int w[ ], int v[ ],int C) { //n个物品,C为最大容量
int i,j;
int V[100][100],x[100];
for (i=0; i<=n; i++) //初始化第0列
V[i][0]=0;
for (j=0; j<=C; j++) //初始化第0行
V[0][j]=0;
//主要背包问题实现
for (i=1; i<=n; i++) //计算第i行,进行第i次迭代
for (j=1; j<=C; j++)
if (j<w[i]) //第i个物品不能装入(超重)
V[i][j]=V[i-1][j];
else //满足装入条件(装入后未超重),但也可不装
V[i][j]=max(V[i-1][j], V[i-1][j-w[i]]+v[i]); //装或者不装后的价值的最大值
//求装入背包的物品:1表示装入,0表示未装入
j=C;
for (i=n; i>0; i--){
if (V[i][j]>V[i-1][j]) {
x[i]=1;
j=j-w[i];
}
else x[i]=0;
}
//输出装入背包的物品:1表示装入,0表示未装入
cout<<"输出装入背包的物品:1表示装入,0表示未装入"<<endl;
for(i=1; i<=n; i++)
cout<<x[i]<<" ";
cout<<endl;
return V[n][C]; //返回背包取得的最大价值
}
int main(){
int n,i,j,w[100],v[100],C;
cout<<"输入物品数量:"<<endl;
cin>>n;
cout<<"输入这"<<n<<"个物品的重量:"<<endl;
for(i=1; i<=n; i++)
cin>>w[i];
cout<<"输入这"<<n<<"个物品的价值:"<<endl;
for(j=1; j<=n; j++)
cin>>v[j];
cout<<"输入背包容量C:"<<endl;
cin>>C;
int rs= KnapSack(n, w, v,C);
cout<<"背包中的物品最大价值容量为:"<<rs<<endl;
return 0;
}
输入物品数量:
3
输入这3个物品的重量:
20 30 10
输入这3个物品的价值:
60 120 50
输入背包容量C:
50
输出装入背包的物品:1表示装入,0表示未装入
1 1 0
背包中的物品最大价值容量为:180
Press any key to continue