题解 | #最大养牛利润#

109 阅读2分钟

描述

在农场里,农民们有一群牛,每头牛的售价和饲养成本不同。农民们将每头牛的利润记录在profits数组中,饲养成本记录在costs数组中。现在农民们想要知道,如果他们只有初始资本w,并且最多只能饲养k头牛,那么他们最终能获得的最大利润是多少。请你编写一个程序,帮助农民们设计完成最多k头牛的饲养计划,以最大化最终利润,并输出最终可获得的最多利润(输出不包括初始资本)。 答案保证在 32 位有符号整数范围内。

示例1

输入:2,0,[2000,3000,4000],[0,1000,1000]
返回值:6000

说明: 由于你的初始资本为 0,你仅可以从 0 号牛开始饲养。 在完成后,你将获得 2000 的利润,你的总资本将变为 2000。 此时你可以选择开始饲养 1 号或 2 号牛。 由于你最多可以选择两头牛,所以你需要饲养 2 号牛以获得最大的利润。 因此,输出最后最大化的利润,为 0 + 2000 + 4000 = 6000。

知识点

贪心

解题思路

使用优先队列来存储一个数组,其中cow[0]表示利润,cow[1]表示饲养成本,利润最大的牛排在队列的前面。

我们将所有牛的利润加入优先队列。由于优先队列是一个最大堆,默认情况下队首元素是利润最大的牛。

然后,我们通过遍历k次的循环来选择饲养k头牛。在每次循环中,如果队列为空或者资本不足以饲养当前利润最大的牛,则将该牛放入到暂存队列中。

否则,我们从队列中取出利润最大的牛,更新可用资本w并加上该牛的利润,将暂存队列中支付不起的牛又放回队列中,然后进入下一次循环。

最终,返回更新后的可用资本w减去成本即可得到最终可获得的最大利润。

Java题解

import java.util.*;


public class Solution {
    public int findMaximizedProfits (int k, int w, int[] profits, int[] costs) {
        // write code here
        int n = profits.length;
        int baseW = w; //初始成本
        // 创建一个优先队列,用于按照利润将牛排序
        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> (b[0] - a[0]));
        for (int i = 0; i < n; i++) {
            pq.offer(new int[] {profits[i], costs[i]});
        }

        for (int i = 0; i < k; i++) {
            // 创建一个临时队列,用于存储可饲养的牛
            PriorityQueue<int[]> tempPq = new PriorityQueue<>((a, b) -> (b[0] - a[0]));

            // 将支付不起的牛放进tempPq
            while (!pq.isEmpty() && w < pq.peek()[1]) {
                int[] cow = pq.poll();
                tempPq.offer(cow);
            }

            // 如果没有可饲养的牛,则结束循环
            if (pq.isEmpty()) {
                break;
            } else {
                int[] cow = pq.poll();
                w += cow[0];
            }

            // 将临时队列中的牛重新放回优先队列
            while (!tempPq.isEmpty()) {
                pq.offer(tempPq.poll());
            }
        }

        return w - baseW;
    }
}