版权声明
- 本文原创作者:谷哥的小弟
- 作者博客地址:http://blog.csdn.net/lfdfhl
题目描述
月饼是中秋佳节传统美食,不同地区有许多不同风味的月饼。现给定每种月饼的库存量、总售价、以及市场的最大需求量,请计算商家可以获得的最大收益。
假如有3种月饼,其库存量分别为18、15、10万吨,总售价分别为75、72、45亿元。假设市场的最大需求量只有20万吨,那么最大收益策略应该是卖出第2种月饼15万吨、第3种月饼5万吨,终于获得 94.5亿元收益。
贪心算法
简单来说,贪心算法就是在做决策时每一步都做出最优的选择,通过每一步的最优选择从而形成整体的最优解。
从题目来看,我们要选出能赚最多钱的销售方式。假设市场有20万吨的需求量,我们有三种月饼,每种月饼的销售组合带来的收益是不同的。我们来想一下什么情况能使收益最大化?先卖出单价最高的月饼,卖完这种月饼之后再卖单价第二高的月饼,直到市场满足需求。
代码实现
具体代码实现如下,仅供参考。
MoonCakeType
package com.algorithm3;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class MoonCakeType {
// 库存量
private double stock;
// 总售价
private double totalPrice;
// 单价
private double unitPrice;
public MoonCakeType() {
}
public MoonCakeType(double stock, double totalPrice) {
this.stock = stock;
this.totalPrice = totalPrice;
this.unitPrice = totalPrice / stock;
}
public double getStock() {
return stock;
}
public void setStock(double stock) {
this.stock = stock;
}
public double getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(double totalPrice) {
this.totalPrice = totalPrice;
}
public double getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(double unitPrice) {
this.unitPrice = unitPrice;
}
@Override
public String toString() {
return "MoonCakeType [stock=" + stock + ", totalPrice=" + totalPrice + ", unitPrice=" + unitPrice + "]";
}
}
Test
package com.algorithm3;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class Test {
public static void main(String[] args) throws Exception {
// 接收用户输入
InputStream inputStream = System.in;
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferReader = new BufferedReader(inputStreamReader);
// 第一行输入内容为:3 20 表示月饼的种类为3;总计需要20万吨
String[] firstInputLine = bufferReader.readLine().split("\\s");
// 第二行输入内容为:18 15 10 表示3种月饼各自的库存,单位为万吨
String[] secondInputLine = bufferReader.readLine().split("\\s");
// 第三行输入内容为:75 72 45 表示3种月饼各自的总价,单位为亿
String[] thirdInputLine = bufferReader.readLine().split("\\s");
// 获取用户输入的月饼品种数
int typeNumber = Integer.valueOf(firstInputLine[0]);
// 获取用户输入的月饼总需求量
double totalDemand = Double.valueOf(firstInputLine[1]);
// 总收益
double maxIncome = 0;
// 获取用户输入的每种月饼的库存和总价
ArrayList<MoonCakeType> moonCakeTypeList = new ArrayList<>();
for (int i = 0; i < typeNumber; i++) {
double stock = Double.valueOf(secondInputLine[i]);
double totalPrice = Double.valueOf(thirdInputLine[i]);
MoonCakeType moonCakeType = new MoonCakeType(stock, totalPrice);
moonCakeTypeList.add(moonCakeType);
}
System.out.println("排序前的月饼:" + Arrays.toString(moonCakeTypeList.toArray()));
// 依据单价将月饼排序
Collections.sort(moonCakeTypeList, new Comparator<MoonCakeType>() {
@Override
public int compare(MoonCakeType mct1, MoonCakeType mct2) {
if (mct2.getUnitPrice() - mct1.getUnitPrice() > 0) {
return 1;
} else {
return -1;
}
}
});
System.out.println("排序后的月饼:" + Arrays.toString(moonCakeTypeList.toArray()));
// 从价格高的月饼开始售卖
for (int i = 0; i < moonCakeTypeList.size(); i++) {
MoonCakeType moonCakeType = moonCakeTypeList.get(i);
double currentIncome = 0;
double currentNumber = 0;
if (moonCakeType.getStock() <= totalDemand) {
// 本次售卖的收益
currentIncome = moonCakeType.getTotalPrice();
// 计算已产生的收益
maxIncome = maxIncome + currentIncome;
// 本次售卖的数量
currentNumber = moonCakeType.getStock();
// 计算剩余需求量
totalDemand = totalDemand - currentNumber;
} else {
// 本次售卖的收益
currentIncome = totalDemand * moonCakeType.getUnitPrice();
// 计算已产生的收益
maxIncome = maxIncome + currentIncome;
// 本次售卖的数量
currentNumber = totalDemand;
// 计算剩余需求量
totalDemand = 0;
}
System.out.println("本次售卖的月饼,单价=" + moonCakeType.getUnitPrice()+"元");
System.out.println("本次售卖的月饼,数量=" + currentNumber+"万吨");
System.out.println("本次售卖的月饼,收益=" + currentIncome+"亿元");
System.out.println("---------------------");
if (totalDemand == 0) {
break;
}
}
// 保留两位小数输出结果
System.out.println(String.format("最终总收益为%.2f亿元", maxIncome));
}
}