05、贪心算法-做项目问题

题目:

输入: 正数数组costs、正数数组profits、正数K、正数M
costs[i]表示i号项目的花费
profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润)
K表示你只能串行的最多做k个项目
M表示你初始的资金
说明: 每做完一个项目,马上获得的收益,可以支持你去做下一个项目。不能并行的做项目。
输出:你最后获得的最大钱数。

1、贪心解决方案

1.1、思路:

 1、准备一个小根堆(项目花费),一个大根堆(项目利润)。
2、按照花费排序,加入到小根堆中
3、每次拿着本金去小根堆里面去判断,把小于等于本金的项目都取出来,然后把这些项目放入到大根堆里面,此时大根堆中堆顶的项目就是需要做的项目,每次都这样重试,直至循环结束

1.2、代码:

/**
 * 求最后获得的最大钱数
 *
 * @param K       做项目的次数
 * @param W       本金
 * @param Profits 利润集合
 * @param Capital 花费集合
 */
public static int findMaximizedCapital(int K, int W, int[] Profits, int[] Capital) {
    //小根堆(花费),项目花费最小的在堆顶
    PriorityQueue<Program> minCostQ = new PriorityQueue<>(new MinCostComparator());
    //大根堆(利润),利润最大的在堆顶
    PriorityQueue<Program> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());
    //按照花费排序,加入到小根堆中
    for (int i = 0; i < Profits.length; i++) {
        minCostQ.add(new Program(Profits[i], Capital[i]));
    }
    for (int i = 0; i < K; i++) {
        //如果小根堆中海油项目,且花费小于本金,那么就可以做这个项目
        while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) {
            //把满足条件的项目加入到大根堆中,利润最大的项目在堆顶位置
            maxProfitQ.add(minCostQ.poll());
        }
        if (maxProfitQ.isEmpty()) {
            return W;
        }
        //做完项目之后,本金增加
        W += maxProfitQ.poll().p;
    }
    return W;
}

public static class Program {
    //利润
    public int p;
    //花费
    public int c;

    public Program(int p, int c) {
        this.p = p;
        this.c = c;
    }
}

public static class MinCostComparator implements Comparator<Program> {

    @Override
    public int compare(Program o1, Program o2) {
        return o1.c - o2.c;
    }

}

public static class MaxProfitComparator implements Comparator<Program> {

    @Override
    public int compare(Program o1, Program o2) {
        return o2.p - o1.p;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值