版权声明:本文为博主原创文章,如有转载或提问请私信 https://blog.csdn.net/ShancoFolia/article/details/72353325
问题描述
话说现在当司机光有红心不行,还要多拉快跑。多拉不是超载,是要让所载货物价值最大,
特别是在当前油价日新月异的时候。司机所拉货物为散货,如大米、面粉、沙石、泥土......
现在知道了汽车核载重量为w,可供选择的物品的数量n。每个物品的重量为gi,价值为pi。
求汽车可装载的最大价值。(n<10000,w<10000,0<gi<=100,0<=pi<=100)
输入格式
输入第一行为由空格分开的两个整数n w
第二行到第n+1行,每行有两个整数,由空格分开,分别表示gi和pi
输出格式
最大价值(保留一位小数)
样例输入
5 36
99 87
68 36
79 43
75 94
7 35
样例输出
71.3
解释:
先装第5号物品,得价值35,占用重量7
再装第4号物品,得价值36.346,占用重量29
下面来重点解析一下这道题的问题出在何处:
话说现在当司机光有红心不行,还要多拉快跑。多拉不是超载,是要让所载货物价值最大,
特别是在当前油价日新月异的时候。司机所拉货物为散货,如大米、面粉、沙石、泥土......
现在知道了汽车核载重量为w,可供选择的物品的数量n。每个物品的重量为gi,价值为pi。
求汽车可装载的最大价值。(n<10000,w<10000,0<gi<=100,0<=pi<=100)
输入格式
输入第一行为由空格分开的两个整数n w
第二行到第n+1行,每行有两个整数,由空格分开,分别表示gi和pi
输出格式
最大价值(保留一位小数)
样例输入
5 36
99 87
68 36
79 43
75 94
7 35
样例输出
71.3
解释:
先装第5号物品,得价值35,占用重量7
再装第4号物品,得价值36.346,占用重量29
最后保留一位小数,得71.3
废话少说,先粘代码
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Scanner;
public class ADV167 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
int n=in.nextInt();//物品数量n
double W=in.nextDouble();//载重w
double[] gi=new double[n];
double[] pi=new double[n];
double[] vi=new double[n];
DecimalFormat df =new java.text.DecimalFormat("#.00000");
int i=0;
for(i=0;i<n;i++){
gi[i]=in.nextInt();
pi[i]=in.nextInt();
vi[i]=Double.parseDouble(df.format(pi[i]/gi[i]));
//System.out.println(df.format(pi[i]/gi[i]));
}
//vi[0]=Double.parseDouble(new java.text.DecimalFormat("#.00000").format(pi[0]/gi[0]));
//vi[2]=pi[2]/gi[2];
in.close();
double sum=0;
double rest=W;//
while(rest>0){
int maxP=max(vi);
if(gi[maxP]<rest){
sum+=pi[maxP];
rest-=gi[maxP];
}
else{
sum+=rest*vi[maxP];
rest=0;
}
vi[maxP]=0;
}
//System.out.println(sum);
System.out.printf("%.1f",sum);
}
private static int max(double[] vi) {
// TODO Auto-generated method stub
int i=0;double max=vi[0];int maxP=0;
for(i=0;i<vi.length;i++){
if(vi[i]>max){
max=vi[i];
maxP=i;
}
}
return maxP;
}
}
下面来重点解析一下这道题的问题出在何处:
首先一开始我在gi和pi的类型上弄错了,我要求平均值,必须用两个double相除,一开始我用两个int相除,最后结果总等于0
第二点是保留了五位的小数的方法
DecimalFormat df =new java.text.DecimalFormat("#.00000");
vi[i]=Double.parseDouble(df.format(pi[i]/gi[i]));
//或者写成
vi[i]=Double.parseDouble(new java.text.DecimalFormat("#.00000").format(pi[i]/gi[i]));
当然,以上代码也可以缩写成:
包括还有最后以一位小数输出,可以用printf这样一个在C语言中就用的语法进行输出,题目不是很难,是背包问题可以切割的那种类型,但是只拿到90分,有一组数据不符合要求,粘贴如下,还望大家帮忙查证:
输入:32 9000
53 17
95 68
35 87
12 2
76 84
67 98
82 19
90 16
83 71
82 7
80 1
80 0
32 42
78 12
43 88
73 97
95 46
35 4
87 98
9 67
16 43
60 98
38 15
67 32
64 82
37 48
71 99
35 79
20 12
12 28
83 39
22 98
正确应输出:1597.0
而我的代码段仅仅在这一个案例上除了问题,请阅读完我代码的同学可以留言一下