任务:背包问题的求解
给定n种物品和一个背包。物品i的重量是Wi,其价值为Vi,背包最大承载重量为C。假设物品是可分割的,应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
定义N个物品的基本数据和背包容量C,编程输出C能装下的最大价值和所选择物品的编号。
#include <stdio.h>
int n;
double c;
double v[999];
double w[999];
double cw = 0.0;
double cp = 0.0;
double bestp = 0.0;
double perp[999];
int order[100];
int put[100];
void sort()
{
int i,j;
int temporder = 0;
double temp= 0.0;
for(i=1;i<=n;i++)
perp[i]=v[i]/w[i];
for(i=1;i<=n-1;i++)
{
for(j=i+1;j<=n;j++)
if(perp[i]<perp[j])
{
temp = perp[i];
perp[i]=perp[j];
perp[j]=temp;
temporder=order[i];
order[i]=order[j];
order[j]=temporder;
temp = v[i];
v[i]=v[j];
v[j]=temp;
temp=w[i];
w[i]=w[j];
w[j]=temp;
}
}
}
void backtrack(int i)
{
double bound(int i);
if(i>n)
{
bestp = cp;
return;
}
if(cw+w[i]<=c)
{
cw+=w[i];
cp+=v[i];
put[i]=1;
backtrack(i+1);
cw-=w[i];
cp-=v[i];
}
if(bound(i+1)>bestp)
backtrack(i+1);
}
double bound(int i)
{
double leftw= c-cw;
double b =cp;
while(i<=n&&w[i]<=leftw)
{
leftw-=w[i];
b+=v[i];
i++;
}
if(i<=n)
b+=v[i]/w[i]*leftw;
return b;
}
int main()
{
int i;
printf("请输入物品的数量和容量:");
scanf("%d%lf",&n,&c);
for(i=1;i<=n;i++)
{
printf("第%d个物品的重量和价值:",i);
scanf("%lf %lf",&w[i],&v[i]);
order[i]=i;
}
sort();
backtrack(1);
printf("最大价值为:%lf\n",bestp);
printf("装入的物品次序为:");
for(i=1;i<=n;i++)
{
if(put[i]==1)
printf("%d ",order[i]);
}
return 0;
}