/**
有n个物体,第i个物体的重量为wi,价值为vi。在总重量不超过C的情况下让总价值尽量高。
每一个物体都可以只取走一部分,价值和重量按比例计算。
求最大总价值
注意:每个物体可以只拿一部分,因此一定可以让总重量恰好为C。
*/
题解:本题通过贪心思想解题,尽可能拿价值高的物品,这样放入背包的价值才最大,但是对价值排序后会使得原来每种物品的重量和价值的对应关系丢失,我们引入物品类,使得每种物品的重量和价值捆绑在一起。最后通过物品类实现Comparable接口,按照价值和重量比排序,最后再从物品数组,从后往前取物品即可。
public class test4 {
public static void main(String[] args) {
int[] w = {1, 2, 3, 4, 5}; //每种物体的重量
int[] v = {3, 4, 3, 1, 4}; //每种物体的价值
int n = w.length; //物体的个数
Obj[] obj=new Obj[n]; //防止排序后物品和对应价值错位,创建对象数组,使得每种物品独立
for (int i = 0; i < n; i++) {
obj[i]=new Obj(w[i],v[i]);
}
Arrays.sort(obj); // 实现obj类的Comparable接口,根据单价进行排序
double C=10; //最大重量
double cur_C=C; //当前还剩的重量;
double maxVal=0; //最大价值
for (int i = n-1; i >=0 ; i--) { //排序后,物品数组最后的物品单价最高,从后开始取物品
if (obj[i].w<=cur_C){ //物品重量小于等于当前还剩的重量,放入背包
maxVal+=obj[i].v;
cur_C -=obj[i].w;
}else{ //物品重量大于当前还剩的重量,物品的一部分放入背包
maxVal+= obj[i].getRate()*cur_C ; //当前物品重量乘以对应物品的单价,就是放入背包的价值
break;
}
}
System.out.println(maxVal);
}
private static class Obj implements Comparable<Obj>{
int w; //物品的重量属性
int v; //物品的价值属性
public Obj(int w, int v) { //构造器
this.w = w;
this.v = v;
}
public double getRate(){ //获取每种物品的单价
return this.v/(double)this.w;
}
@Override
public int compareTo(Obj ohter) { //实现compareto接口,根据单价进行比较
if (this.getRate()==ohter.getRate()) return 0;
else if (this.getRate()>ohter.getRate()) return 1;
else return -1;
}
}
}