java贪心算法经典案例之项目利润最大问题

Posted wen-pan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java贪心算法经典案例之项目利润最大问题相关的知识,希望对你有一定的参考价值。

1、问题描述

输入:

正数数组costs
正数数组profits
正数k
正数m

含义:

costs[i]表示i号项目的花费

profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润)

k表示你只能串行的最多做k个项目

m表示你初始的资金

说明:

你每做完一个项目,马上获得的收益,可以支持你去做下一个项目。

输出:

你最后获得的最大钱数。

2、问题分析

该问题很明显是一个贪心相关的问题,我们每次做项目的时候都选择项目成本在我的启动资金之内,并且利润最大的项目来做,这样是不是就做到了项目的利润最大化。

这里我们考虑使用两个堆来完成该贪心算法:一个大根堆(按项目利润组织)一个小根堆(按项目花费组织的)

①、首先将每个项目的启动资金(花费)和该项目的利润组成一个个的节点

②、将第一步组成的节点添加到一个小根堆里(添加完成后该小根堆就不动了,仅供每次从这个小根堆里挑选项目)。

③、每次挑一个在我们启动资金范围内且利润最大的项目。最多做k个项目,每次挑一个项目做,则我们需要挑的项目一定是花费在我们启动资金以内,并且他的利润一定是最大的。所以我们每次挑项目的时候:

1、首先根据我们的现有启动资金,从小根堆里挑选出所有项目成本小于我们的启动资金的项目。

2、将挑出来的项目全部放入到一个大根堆里(按利润组织的)

3、然后从大根堆里拿出堆顶项目(该项目就是满足项目成本在启动资金内,且利润最大的项目)

4、累加上面的项目所获得的利润。继续挑选下一个项目

3、代码实现

/**
 * 贪心算法求做项目最大利润问题
 *
 * @param k       最多能做的项目数量
 * @param w       启动资金
 * @param profits 每个项目的利润
 * @param capital 每个项目的成本
 * @return: int
 */
public static int findMaximizedCapital(final int k, int w, final int[] profits, final int[] capital) {

    // 小根堆,按照每个项目的最小花费(成本)构建成小根堆
    final PriorityQueue<Node> minCostQueue = new PriorityQueue<>();
    // 大根堆,按照每个项目的利润构建成一个大根堆
    final PriorityQueue<Node> maxProfitQueue = new PriorityQueue<>();

    // 先将每个项目的成本和利润组织为一个个的节点并放入到小根堆中
    for (int i = 0; i < profits.length; i++) {
        minCostQueue.add(new Node(profits[i], capital[i]));
    }

    // 开始做项目,每次循环代表做一个项目
    for (int i = 0; i < k; i++) {

        // 取出我当前启动资金能做的所有项目(即:项目成本小于我的启动资金的项目),放入到大根堆中
        // 注意这里peek和poll的区别,peek 不会删除元素,poll 会删除元素
        while (!minCostQueue.isEmpty() && minCostQueue.peek().cost <= w) {
            maxProfitQueue.add(minCostQueue.poll());
        }

        // 这里需要特别注意,很容易被忽视掉
        // 如果 maxProfitQueue 为空,则表示按照当前的启动资金,已经没有办法从小根堆(minCostQueue)里取出任何一个项目来做了
        if (maxProfitQueue.isEmpty()) {
            return w;
        }

        // 每次挑一个项目成本在我启动范围之内,并且利润最大的项目做
        final Node project = maxProfitQueue.poll();
        // 每个项目做完后,启动资金增加
        w = w + project.profit;
    }

    return w;
}

以上是关于java贪心算法经典案例之项目利润最大问题的主要内容,如果未能解决你的问题,请参考以下文章

贪心算法 -- 121. 买卖股票的最佳时机

一文通数据结构与算法之——贪心算法+常见题型与解题策略+Leetcode经典题

47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题

数据结构与算法笔记(十七)—— 贪心算法及经典案例(找零问题背包问题拼接最大数字问题活动选择问题)

数据结构与算法笔记(十七)—— 贪心算法及经典案例(找零问题背包问题拼接最大数字问题活动选择问题)

(贪心算法)Java 求解跳跃游戏