给定个物品和一个容量为的背包,物品i的重量是,其价值为。背包问题是如何选择装入背包的物品,使得装入背包中的物品总价值最大?(物品可以分割)
Input
单组数据输入。
第一行:两个整数和。表示物品的个数和背包的容量。
下面有行,每行有两个整数和,分别表示每个物品的重量和价值。
Output
第一行:一个浮点数,表示能装入背包的最大价值。保留小数点后两位
第二行:个整数,表示个物品装入背包的重量。并以空格隔开。(按输入顺序排列,即第一个数为物品1装入背包的重量)
Sample input
3 50
20 60
30 120
10 50
Sample output
200.00
10 30 10
#include <iostream>
#include <algorithm>
#include<iomanip>
#include<stdio.h>
#define MAX_NUM 1000
using namespace std;
struct Goods //info of goods定义物品信息结构体
{
int weight;// the weight of goods重量
int value;// the value of goods价值
double ValPerWei;// value per weight权重
double load; //物品装入背包的部分的系数(物品全部装入则load为1,装入10/20则load为0.5)
int id;
};
int cmp( Goods const &a, Goods const &b)//定义sort函数的比较函数
{
if(a.ValPerWei<b.ValPerWei) return 0;
else return 1;
}
void Greedy(Goods g[],int good_num, int content)//贪心算法
{
for(int i=0; i<good_num; i++)
{
if(content>g[i].weight)//如果背包足够装下整个物品
{
content-=g[i].weight;
g[i].load=1;
}
else if(content>0){//如果背包不足以装下整个物品
g[i].load=(double)content/g[i].weight;//计算物品装入背包的部分
content=0;//背包容量置0
return;//程序结束,返回
}
}
}
int main()
{
int goods_num;
double bagvol;
double total_value=0;
double total_weight=0;
int ib=0;
cin>>goods_num>>bagvol;
Goods G[goods_num+1];
for(int i=0; i<goods_num; i++)
{
cin>>G[i].weight>>G[i].value;//输入重量价值
G[i].ValPerWei=(double)G[i].value/G[i].weight;//计算权重
G[i].load=0;//load置0
G[i].id=ib;
ib++;
}
sort (G,G+goods_num,cmp);//sort by ValPerWei
Greedy(G,goods_num,bagvol);
for(int i=0;i<goods_num;i++)//output the info of goods
{
if(G[i].load==0.0)break;//如果检测到物品未被装入背包,则推出循环
total_value+=(G[i].value*G[i].load);//装入背包的物品总价值
total_weight+=(G[i].weight*G[i].load);//装入背包的物品总重量
//cout<<"weight: "<<G[i].weight<<" "<<"value: "<<G[i].value<<" "<<"the value per weight of good: "<<G[i].ValPerWei<<" the part of goods: "<<G[i].load<<endl;//输出装入背包的物品信息
}
printf("%.2lf",total_value);//输出装入物品的总价值
cout<<endl;
int j=0,i=0;
for( j=0;j<goods_num;j++)
{
for(i=0;i<goods_num;i++)
{
if(G[i].id==j&&j!=goods_num-1)
cout<<G[i].load*G[i].weight<<" ";
else if(G[i].id==j&&j==goods_num-1)
cout<<G[i].load*G[i].weight<<endl;
}
}
}