【ShawnZhang】带你看蓝桥杯——算法提高 快乐司机

版权声明:本文为博主原创文章,如有转载或提问请私信 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

最后保留一位小数,得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

而我的代码段仅仅在这一个案例上除了问题,请阅读完我代码的同学可以留言一下



猜你喜欢

转载自blog.csdn.net/ShancoFolia/article/details/72353325