给定n种物品和一个背包。物品i的重量是Wi,其价值为Vi,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
//时间复杂度 o(nlogn)(排序)+o(n)(挑选)
#include <stdio.h>
#define MAX 1000
struct object{
int weight;//重量
int value;//价值
double rate;//性价比
double choose;//装多少
}obj[MAX];//定义一个obj数组
void knap();
int n,c;//n种物品,背包容量c
void quick_sort(struct object* obj,int low,int high);
int main()
{
printf("请输入物品个数:\n");
scanf("%d",&n);
printf("请输入%d个物品对应的重量和价格:\n",n);
for(int i=0;i<n;i++)
{
scanf("%d",&obj[i].weight);
scanf("%d",&obj[i].value);
// printf("\n");
obj[i].rate=(double)obj[i].value/obj[i].weight;
obj[i].choose=0;
}
printf("请输入背包容量:\n");
scanf("%d",&c);
quick_sort(obj,0,n-1);
knap();
return 0;
}
void knap()
{
double allvalue=0;//最大价值
double allweight=0;//总重量
for(int i=0;i<n;i++)
{
if(obj[i].weight<=c)//加入整个
{
allvalue+=obj[i].value;
allweight+=obj[i].weight;
obj[i].choose=1;
c-=obj[i].weight;
}
else//没加完
{
double a=(double)c/obj[i].weight;//看加多少
allvalue+=obj[i].value*a;
allweight+=obj[i].weight*a;
obj[i].choose=a;
break;
}
}
printf("总价:%.2f\n总重:%.2f\n",allvalue,allweight);
printf("选择了以下物品:\n");
for(int i=0;i<n;i++)
{
if(obj[i].choose>0&&obj[i].choose<1)
printf("%d号 装入百分之%.1f \n",i,obj[i].choose*100);
if(obj[i].choose==1)
printf("%d号\n",i);
}
}
void quick_sort(struct object* obj,int low,int high)//从大到小排序
{
if(low>=high)
return;
int i=low,j=high;
struct object tmp=obj[low];//基元
struct object temp;//交换的时候临时用一下
while(i!=j)
{
while(obj[j].rate<=tmp.rate&&i<j)
j--;
while(obj[i].rate>=tmp.rate&&i<j)
i++;
if(i<j)
{
temp=obj[i];
obj[i]=obj[j];
obj[j]=temp;
}
}
obj[low]=obj[i];
obj[i]=tmp;
quick_sort(obj,low,i-1);
quick_sort(obj,i+1,high);
}