藍橋杯-算法提高(貪心算法):快樂司機

問題描述:

問題描述

  "嘟嘟嘟嘟嘟嘟
  喇叭響
  我是汽車小司機
  我是小司機
  我爲祖國運輸忙
  運輸忙"
  這是兒歌“快樂的小司機”。話說現在當司機光有紅心不行,還要多拉快跑。多拉不是超載,是要讓所載貨物價值最大,特別是在當前油價日新月異的時候。司機所拉貨物爲散貨,如大米、麪粉、沙石、泥土......
  現在知道了汽車核載重量爲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

問題分析:

根據題目所述的要求,該題的解題關鍵在於找出裝貨物的順序,使得在裝滿貨車的最大重量情況下的價值最高。

關鍵點:

找出各個貨物的價值效益,將價值效益較高的物品先裝上車,然後一次將價值效益較低的裝車。根據題目給出的重量和價值可以算出每種貨物每個單位量的價值,每個單位量價值最高的產生的效益越高,所以優先裝車。

解題步驟:

首先通過鍵盤將所有的數據都得到,用重量和價值算出每個貨物的價值重量比。

然後按價值重量比從高到底的順序裝車,只有在最後一次裝車時不能全部裝完

最後一種裝車的貨物只能裝一部分,所以用剩餘重量和價值重量比相乘得到該貨物裝上車的價值

把所有的裝車貨物的價值相加即可算出最大價值

詳細代碼:

package happyDriver;
import java.util.Scanner;
import java.math.BigDecimal;

public class Main {
	public static void main(String args[]) {
		@SuppressWarnings("resource")
		Scanner input = new Scanner(System.in);
//		輸入貨物種類
		int classes = input.nextInt();
//		輸入總載貨量
		float weight = input.nextFloat();
		float each_price[] = new float[classes];
		float each_weight[] = new float[classes];
//		輸入每種貨物的價值和重量
		for(int i =0;i<classes;i++) {
			each_weight[i] = input.nextFloat();
			each_price[i] = input.nextFloat();
		}
//		測試輸入數據的正確性
//		for(int i = 0;i<classes;i++) {
//			System.out.println("wight:"+each_weight[i]+"  price:"+each_price[i]);
//		}
		

		float benefit[] = new float[classes];
//		計算每種貨物的價值比
		for(int i = 0;i<classes;i++) {
			benefit[i] = each_price[i] / each_weight[i];
			BigDecimal b = new BigDecimal(benefit[i]);  
			benefit[i] = b.setScale(3,BigDecimal.ROUND_HALF_UP).floatValue();  
			
			
		}
	
//		測試貨物價值比正確性
//		for(int i = 0;i<classes;i++) {
//			System.out.println(benefit[i]);
//		}
		float sum_weight = 0;
		float sum_price = 0;
		int k = 0;
		float max;
		for(int i = 0;i<classes;i++) {
			max = 0;
//			尋找最大價值比商品
			for(int j = 0;j<classes;j++) {
				if(benefit[j] >= max) {
					max = benefit[j];
					k = j;
				}
			}
//			System.out.println("benefit:"+benefit[k]+" index:"+k);
//			將當前貨物的全部裝入貨車
			if(sum_weight + each_weight[k] <= weight) {
				sum_price += each_price[k];
				sum_weight += each_weight[k];
				
			}
//			將當前貨物的部分裝入貨車
			else {
				sum_price += (weight - sum_weight) * benefit[k];
				break;
			}
			benefit[k] = -1;
			
		}
//		保留一位小數並輸出總價值
		BigDecimal b = new BigDecimal(sum_price);  
		sum_price = b.setScale(1,BigDecimal.ROUND_HALF_UP).floatValue();  
		System.out.println(sum_price);
		
	}

}

注意:

因爲該方法算出的價值重量比是小數,所以應該按要求進行四捨五入,最後得到的最大價值只用保留一位小數

此外因爲我在寫該算法時找最大價值重量比是用的循環遍歷的方法,所以耗費的時間會比較多,最後得到的測試結果可能會出現超時的情況

提問:

在Java中如何能快速找到數組中的最大值並返回它的索引,希望大神們能夠指點指點,謝謝。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章