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

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

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

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

输入例子:
3 20
18 15 10
75 72 45

输出例子:
94.50

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @ProjectName: 20201019牛客刷题
 * @Package: test
 * @ClassName: MoonCake
 * @Author: 民
 * @Description: 月饼
 * @Date: 2020/10/20 17:44
 * @Version: 1.0

 */
public class MoonCake {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //1.记录数据
        //月饼种类数 背包容量
        //每种月饼的总价格 每种月饼的总重量
        //单位月饼的价值
        //标记数组
        String[] values1 = br.readLine().split(" ");
        int n = Integer.parseInt(values1[0]);//n是月饼种类数
        int w = Integer.parseInt(values1[1]);//w是背包容量
        String[] values2 = br.readLine().split(" ");
        String[] values3 = br.readLine().split(" ");
        int[] v = new int[n];//存放价格
        int[] weight = new int[n];//存放重量
        for (int i = 0; i < n; i++) {
            v[i] = Integer.parseInt(values3[i]);
            weight[i] = Integer.parseInt(values2[i]);
        }
        double[] value_s = new double[n];//单位价格
        boolean[] flag = new boolean[n];//标记
        for (int i = 0; i < values2.length; i++) {
            value_s[i] = Double.parseDouble(values3[i])/Double.parseDouble(values2[i]);
        }
        //2. 贪心算法,每次放最大价值的物品 直到背包放满了
        double money = 0;
        while (w>0){
            int index = findMax(value_s,flag);//2.1 找到当前数组最大值,注意此时要选择没有被标记过的月饼
            if(w>weight[index]){//2.2 当前背包充裕,将整一种月饼全都放入背包
                w-=weight[index];//背包容量减少
                money+=v[index];//盈利增多
                flag[index]=true;//标记数组,表明已经被拿走了
            }else {//2.3 若当前月饼不能完全放下了,只剩下一点空间
                money += w*value_s[index];//能放多少放多少,能赚多少是多少
                break;
            }
        }
        System.out.printf("%.2f",money);
    }
    public static int findMax(double[] v,boolean[] flag){//根据两个数组找到当前数组的最大值索引位置
        int index=0;
        double max = v[0];
        for (int i = 0; i < v.length; i++) {
            if (max<=v[i]&&!flag[i]){
                max = v[i];
                index = i;
            }
        }
        return index;
    }
}