问题描述:
有n个物体 对应重量为wi,对应价值为vi,最大容量为C。
每一个物体都可以只取走一部分价值和重量按比例计算。
求所能容纳的最大价值。
样例输入:
6 //n
1 2 3 4 5 6 //w
1 6 8 7 4 6 //v
12 //C
样例输出:
24.0
思路分析:
首先将物体的重量和价值进行类绑定,建立对象数组,对其按照单位价值大小进行排序,而后取从最大到最小的价值,直到总重量大于C即可。
具体看代码注释:
import java.util.Arrays;
import java.util.Scanner;
public class Bfbb {
//部分背包问题
//有n个物体 对应重量为wi,对应价值为vi,最大容量为C,求所能容纳的最大价值
private static class wv implements Comparable<wv>{
int w;
double v;
public wv(int w, double v) {//构造器
this.w = w;
this.v = v;
}
public double getprice()//计算单位价值
{
return this.v/this.w;
}
@Override
public int compareTo(wv o) {//按照单位价值进行排序
if (this.getprice()==o.getprice()) return 0;
else if (this.getprice()>o.getprice()) return 1;
else return -1;
}
@Override
public String toString() {//重写tostring方法
return this.w+" "+this.v;
}
}
public static void main(String[] args) {
Scanner a=new Scanner(System.in);
int n=a.nextInt();//输入物体个数
int []w=new int[n];//输入对应的重量
double []v=new double[n];//输入对应价值
for (int i=0;i<n;i++)
w[i]=a.nextInt();
for (int i=0;i<n;i++)
v[i]=a.nextDouble();
int C=a.nextInt();//输入背包容量C
wv []wvs=new wv[n];
for (int i = 0; i <n ; i++) {
wvs[i]=new wv(w[i],v[i]);
}
Arrays.sort(wvs);//对对象数组进行排序
System.out.println(Arrays.toString(wvs));//输出排序后的对象数组
int temp=0;//记录所加的重量之和
double maxvalue=0;
for (int i = n-1; i>=0; i--) {
temp+=wvs[i].w;
if (temp<=C)
maxvalue+=wvs[i].v;
else
{
maxvalue+=(C-temp+wvs[i].w)*wvs[i].getprice();
break;
}
}
System.out.println(maxvalue);
}
}
运行效果如下:
倒数第二行输出按照单位价值排序后的对象数组。