给定n个物品和一个容量为C的背包,物品i的重量是wi,其价值为vi。背包问题是如何选择装入背包的物品,使得装入背包中的物品总价值最大?(物品可以分割)
Input
单组数据输入。
第一行:两个整数n和C。表示物品的个数和背包的容量。(1≤n≤1000,0≤C≤100000)
下面有n行,每行有两个整数wi和vi,分别表示每个物品的重量和价值。(0≤wi≤1000,0≤vi≤1000)
Output
第一行:一个浮点数,表示能装入背包的最大价值V。V保留小数点后两位
第二行:n个整数,表示n个物品装入背包的重量。并以空格隔开。(按输入顺序排列,即第一个数为物品1装入背包的重量)
Sample Input
3 50
20 60
30 120
10 50
Sample Output
200.00
10 30 10
Hint
贪心策略
10×3+30×4+10×5=200
ac代码:
#include <bits/stdc++.h>
using namespace std;
struct hhh{
double w,v,d=-1;
int in=0,cut=0;
};
bool cmp(hhh x,hhh y){//按单位质量价值排序
return x.d>y.d;
}
bool cmp2(hhh x,hhh y){
return x.in<y.in;
}
int main(){
int n,i,j;
double c;
double res=0;
cin>>n>>c;
hhh a[n];
for(i=0;i<n;i++){
cin>>a[i].w>>a[i].v;
a[i].in=i;//记录顺序
if(a[i].w!=0)
a[i].d=a[i].v/a[i].w;
}
sort(a,a+n,cmp);
for(i=0;i<n;i++)
if(a[i].w==0)//将质量为0的物品放入背包
res+=a[i].v;
for(i=0;i<n;i++){
if(a[i].w==0)
continue;
if(a[i].w<c){//将整体能放进去的放入背包
c=c-a[i].w;
res+=a[i].v;
a[i].cut=a[i].w;
}
else{//将不能整体放入的背包分割放入
res+=c*a[i].d;
a[i].cut=c;
break;
}
}
printf("%.2lf\n",res);
sort(a,a+n,cmp2);//回到原本的排序
//输出装入背包的物品质量
for(i=0;i<n;i++){
if(i)
cout<<" "<<a[i].cut;
else
cout<<a[i].cut;
}
cout<<endl;
return 0;
}
可分割的背包问题重点在排序。