问题描述
给定n种物品和一背包。物品i的重量为wi,其价值为vi, 背包容量为c。问应如何选择装入背包中的物品,使得背入背包的物品的总价值最大?
完整代码
#include "stdafx.h"
int n;//物品的个数
int c;//背包的容量
int bestp;//最大价值(最优值)
int p[20],w[20];//存每个物品的价值和重量
int x[20],bestx[20];
int Bound(int i, int cp,int cw){//限界函数
int cleft=c-cw;//剩余容量
int b=cp;
//以物品单位重量价值递减次序装入物品
while(i<=n && w[i]<cleft)
{
cleft-=w[i];
b+=p[i];
i++;
}
//装满背包
if(i<=n){
b+=p[i]*cleft/w[i];
return b;
}
}
void Backtrack(int i,int cp,int cw){
if(i>n){//回溯结束
if(cp>bestp){//cp当前包内物品价值
bestp=cp;
for(i=1;i<=n;i++){
bestx[i]=x[i];
}
}
return;
}
if(cw+w[i]<=c){ //进入左子树
x[i]=1;
cw+=w[i];
cp+=p[i];
Backtrack(i+1,cp,cw);
cw-=w[i];
cp-=p[i];
}
if(Bound(i+1,cp,cw)>bestp){ //进入右子树
x[i]=0;
Backtrack(i+1,cp,cw);
}
}
int main(int argc, char* argv[])
{
int i;
printf("请输入物品的数量:\n");
scanf("%d",&n);
printf("请输入每个物品的重量和价值:\n");
for(i=1;i<=n;i++) {
scanf("%d%d",&w[i],&p[i]);
}
printf("请输入背包的容量:\n");
scanf("%d",&c);
Backtrack(1,0,0);
printf("最大价值为:\n%d",bestp);
printf("\n最优解为:\n");
for(i=1;i<=n;i++)
{
printf("%d ",bestx[i]);
}
printf("\n");
return 0;
}
测试
**测试过程:**运行程序,根据提示输入物品的数量,每个物品的重量和价值以及背包的容量,回车后系统显示最大的价值即最优值和最优解。
问题讨论
**讨论时间复杂度:**在最坏的情况下,所搜索的结果是一个满二叉树,此时相当于采用的就是穷举法,时间复杂度为,而每次决定是否要讲n个物品放入背包都要进行比较,这一步的时间复杂度为n,所以最坏情况下时间复杂度为
。