1. 程式人生 > >PAT乙級——1020(貪心演算法)

PAT乙級——1020(貪心演算法)

題目:月餅 (25 分)

月餅是中國人在中秋佳節時吃的一種傳統食品,不同地區有許多不同風味的月餅。現給定所有種類月餅的庫存量、總售價、以及市場的最大需求量,請你計算可以獲得的最大收益是多少。

注意:銷售時允許取出一部分庫存。樣例給出的情形是這樣的:假如我們有 3 種月餅,其庫存量分別為 18、15、10 萬噸,總售價分別為 75、72、45 億元。如果市場的最大需求量只有 20 萬噸,那麼我們最大收益策略應該是賣出全部 15 萬噸第 2 種月餅、以及 5 萬噸第 3 種月餅,獲得 72 + 45/2 = 94.5(億元)。

輸入格式: 每個輸入包含一個測試用例。每個測試用例先給出一個不超過 1000 的正整數 N 表示月餅的種類數、以及不超過 500(以萬噸為單位)的正整數 D 表示市場最大需求量。隨後一行給出 N 個正數表示每種月餅的庫存量(以萬噸為單位);最後一行給出 N 個正數表示每種月餅的總售價(以億元為單位)。數字間以空格分隔。

輸出格式: 對每組測試用例,在一行中輸出最大收益,以億元為單位並精確到小數點後 2 位。

輸入樣例:
3 20
18 15 10
75 72 45

輸出樣例:
94.50

題目分析及實現

題目很明顯是一個貪心演算法,但是由於題目不難,所以先不考慮動態規劃。只是求出月餅的單位價值,並從高到低排序。按照庫存量進行計算和選擇。

//三個用例超時,只有十五分,只能說,java太容易超時,如果是為了刷PAT分數或考試,建議轉C++
//語言大同小異,原理都是一樣的
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

class
MoonCake implements Comparable<MoonCake>{ double repertory,price; double averageSelling; @Override public int compareTo(MoonCake o) { averageSelling=price/repertory; int result ; double temp=this.averageSelling-o.averageSelling; if(temp>0.0f) result=
-1; else result=1; return result; } } public class Main { public static void main(String []args){ Scanner in =new Scanner(System.in); int type =in.nextInt(); int allNeed=in.nextInt(); double price=0.0f;//所有月餅的總售價 double remain=0;//所有月餅的總庫存 MoonCake[] a=new MoonCake[type]; Set<MoonCake>set=new TreeSet<>(); for(int i=0;i<type;i++){ a[i]=new MoonCake(); a[i].repertory=in.nextDouble(); remain+=a[i].repertory; } for(int i=0;i<type;i++){ a[i].price=in.nextDouble(); price+=a[i].price; set.add(a[i]); } in.close(); if(remain<allNeed) System.out.printf("%.2f",price); else{ price=0.0f; remain=allNeed; for(MoonCake moonCake:set){ if(remain<moonCake.repertory){ price+=moonCake.averageSelling*remain; break; }else { price+=moonCake.price; remain-=moonCake.repertory; } } } System.out.printf("%.2f",price); } }