贪心算法-项目收益问题
题目:
输入:
正数数组costs :costs[i]表示i号项目的花费
正数数组profits :profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润)
正数k :能串行的最多做k个项目
正数m :初始的资金
输出:
你最后获得的最大钱数。
solution:
1、建立一个小根堆(被锁池,按照起始资金进行排序,不分利润大小)和一个大根堆(解锁池,按照利润进行排序) 2、先把所有项目放入小根堆 3、小根堆中弹出所有满足起始资金的一批,放入大根堆 4、大根堆弹出一个项目(获得了利润最大的一个项目A) 5、根据项目A的钱去小根堆中解锁能做的项目 循环2,3,4
代码实现
package Algorithms.greed; import java.util.Comparator; import java.util.PriorityQueue; public class IPO { //项目模型 public static class Node { public int p; //利润 public int c; //花费 public Node(int p, int c) { this.p = p; this.c = c; } } //根据花费构建小根堆 的比较器 public static class MinCostComparator implements Comparator<Node> { @Override public int compare(Node o1, Node o2) { return o1.c - o2.c; } } //根据利润构建大根堆 的比较器 public static class MaxProfitComparator implements Comparator<Node> { @Override public int compare(Node o1, Node o2) { return o2.p - o1.p; } } public static int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) { //构建项目 // Node[] nodes = new Node[Profits.length]; // for (int i = 0; i < Profits.length; i++) { // nodes[i] = new Node(Profits[i], Capital[i]); // } PriorityQueue<Node> minCostQ = new PriorityQueue<>(new MinCostComparator()); PriorityQueue<Node> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator()); for (int i = 0; i < Profits.length; i++) { //把所有项目扔到被锁池中(花费构建的小根堆) minCostQ.add(new Node(Profits[i], Capital[i])); } for (int i = 0; i < k; i++) { //进行k轮 //符合启动资金的项目全部解锁 while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) { maxProfitQ.add(minCostQ.poll()); } if (maxProfitQ.isEmpty()) { //无项目可挑(启动资金不满足后面的项目) return W; } W += maxProfitQ.poll().p; //利润累加 } return W; } }