月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。

注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有 3 种月饼,其库存量分别为 18、15、10 万吨,总售价分别为 75、72、45 亿元。如果市场的最大需求量只有 20 万吨,那么我们最大收益策略应该是卖出全部 15 万吨第 2 种月饼、以及 5 万吨第 3 种月饼,获得 72 + 45/2 = 94.5(亿元)。

输入格式:

每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数 N 表示月饼的种类数、以及不超过 500(以万吨为单位)的正整数 D 表示市场最大需求量。随后一行给出 N 个正数表示每种月饼的库存量(以万吨为单位);最后一行给出 N 个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。

输出格式:

对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后 2 位。

输入样例:

  1. 3 20
  2. 18 15 10
  3. 75 72 45

输出样例:

  1. 94.50

思路

  1. 总是选择单价最高的月饼,由此获得最大利润

    • 库存量总销售价 来计算月饼单价
    • 把月饼单价由 高到低 排序
  2. 从单价高的月饼开始枚举

    1. 如果 库存量 < 需求量,则该类月饼全卖掉;此时 需求量 = 需求量 - 该类月饼库存量,收益值 += 该类月饼总销售量
    2. 如果 库存量 > 需求量,则要多少给多少;此时 收益值 = 需求量 * 月饼单价,而后需求量减为0

代码

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. struct mooncake {
  5. double store;
  6. double price;
  7. double totalSell;
  8. }cake[1001];
  9. bool cmp(mooncake a, mooncake b) { /* 价格谁高谁在前面 */
  10. return a.price > b.price;
  11. }
  12. int main() {
  13. int number;
  14. double needNumber;
  15. scanf("%d %lf", &number, &needNumber);
  16. /** 读入数据,给mooncake对象贴标签 */
  17. for(int i = 0; i < number; i++) {
  18. scanf("%lf", &cake[i].store);
  19. }
  20. for(int i = 0; i < number; i++) {
  21. scanf("%lf", &cake[i].totalSell);
  22. cake[i].price = cake[i].totalSell / cake[i].store; /* 计算单价 */
  23. }
  24. /** 按价格由高到低排序 */
  25. sort(cake, cake + number, cmp);
  26. /** 计算利润 */
  27. double earnings = 0;
  28. for(int i = 0; i < number; i++) {
  29. if(cake[i].store <= needNumber) { /* 库存量 <= 需求量 */
  30. needNumber = needNumber - cake[i].store;
  31. earnings += cake[i].totalSell;
  32. }
  33. else { /* 库存量 >= 需求量 */
  34. earnings = earnings + (cake[i].price * needNumber);
  35. break;
  36. }
  37. }
  38. /** 展示利润 */
  39. printf("%.2f\n", earnings);
  40. return 0;
  41. }