贪心算法之利润最大问题

力扣第502题:

题目解释:

每个项目有不同的花费,也有不同的利润,capital数组就是项目的花费,profit数组就是项目的利润,索引i就是对应的项目,给定启动资金W,最多完成K个项目,怎么安排利润最大,求最大利润

解题步骤:

1.定义项目类(Project),两个属性:项目花费cost和项目利润profit

2.定义一个小根堆、一个大根堆,小根堆以项目花费最少的排序,大根堆暂时位空

3.从小根堆弹出项目,如果项目花费小于启动资金W,那么就把满足条件的项目全部加入大根堆,大根堆以利润最大排序(注意提前自定义比较器,因为Project类是自定义的,没有比较器的话系统不知道怎样比大小)

4.从大根堆依次拿出项目,将利润累加到W,直到大根堆为空或者小根堆的项目都大于启动资金W结束

整体代码:

import java.util.Comparator;
import java.util.PriorityQueue;

/**
 * 题目解释:
 * 初始资金W,最多最K个项目,每个项目可以挣到不等的钱,求怎么组合挣到的钱最多?
 */
public class Code_502 {

    public static class Project {
        public int cost;
        public int profit;

        public Project(int cost, int profit) {
            this.cost = cost;
            this.profit = profit;
        }
    }

    //花费较小的排在前面的比较器
    public static class CostComparator implements Comparator<Project> {
        @Override
        public int compare(Project o1, Project o2) {
            return o1.cost - o2.cost;
        }
    }

    //利润大的排在前面的比较器
    public static class ProfitComparator implements Comparator<Project> {
        @Override
        public int compare(Project o1, Project o2) {
            return o2.profit - o1.profit;
        }
    }

    public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
        PriorityQueue<Project> costHeap = new PriorityQueue<>(new CostComparator());
        for (int i = 0; i < profits.length; i++) {
            costHeap.add(new Project(capital[i], profits[i]));
        }
        PriorityQueue<Project> profitHeap = new PriorityQueue<>(new ProfitComparator());
        for (int i = 0; i < k; i++) {
            while (!costHeap.isEmpty() && costHeap.peek().cost <= w) {
                profitHeap.add(costHeap.poll());//把小根堆里面能做的项目拿到大根堆
            }
            if (profitHeap.isEmpty()) {//如果小根堆的项目所需资金都大于启动资金w,那么没有项目可做,大根堆为空
                return w;
            }
            w += profitHeap.poll().profit;
        }
        return w;
    }
}
经验分享 程序员 微信小程序 职场和发展