问题 G: 部分背包问题
时间限制: 1 Sec 内存限制: 128 MB
提交: 284 解决: 162 201501010119
提交状态讨论版
题目描述
给定n种物品和一个背包,物品i的重量是Wi,其价值为Vi,背包的容量为C。如何选择装入背包的物品(物品可以被分割),可以使得装入背包中物品的总价值最大?
输入
每组输入包括三行,
第一行包括物品个数n,以及背包容量C。
第二、三行包括两个一维数组,分别为每一种物品的价值和重量。
输出
背包的最大总价值(保留到小数点后两位)
样例输入 Copy
5 10
6 3 5 4 6
2 2 6 5 4
样例输出 Copy
16.67
分析:
需要用到implements Comparator<>来进行某种方式的排序‘
最后在排序的时候用 Arrays.sort(A,1,n+1,new cmp());
代码:
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
//结构体
class Element
{
double w;
double v;
double p;
};
//自定义以单位重量价值排序排序
class cmp implements Comparator<Element>
{
public int compare(Element a, Element b) {
if(a.p<b.p)
{
return 1;
}
else{
return -1;
}
}
}
public class Main {
static double value;
static double[] x=new double[100];
static int c;
static Element[] A;
static void knapsack() //求解背包问题并返回总价值
{
value=0; //初始化最大价值为0
double weight=c; //背包中能够装入的剩余重量
int i=1;
while(A[i].w<weight) //物品i能够全部装入时循环
{
x[i]=1; //装入物品i
weight-=A[i].w; //减少背包中能装入的剩余重量
value+=A[i].v; //累计总价值
i++; //继续循环
}
if(weight>0) //余下重量大于0
{
x[i]=weight/A[i].w; //将物品i的一部分装入
value+=x[i]*A[i].v; //累计总价值
}
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
{
while(scan.hasNext())
{
int n=scan.nextInt();
c=scan.nextInt();
A=new Element[n+1];
for(int i=1; i<=n; i++)
{
A[i]=new Element();
A[i].v=scan.nextDouble();
}
for(int i=1; i<=n; i++)
{
A[i].w=scan.nextDouble();
}
for(int i=1; i<=n; i++)
{
A[i].p=A[i].v/A[i].w;
}
Arrays.sort(A,1,n+1,new cmp());
knapsack();
System.out.println(String.format("%.2f",value));
}
}
}
}