题目:假设 力扣(LeetCode)即将开始其 IPO。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目。帮助 力扣 设计完成最多 k个不同项目后得到最大总资本的方式。
给定若干个项目。对于每个项目 i,它都有一个纯利润 Pi,并且需要最小的资本 Ci 来启动相应的项目。最初,你有 W 资本。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。
总而言之,从给定项目中选择最多 k 个不同项目的列表,以最大化最终资本,并输出最终可获得的最多资本。
示例:
输入: k=2, W=0, Profits=[1,2,3], Capital=[0,1,1].
输出: 4
解释:
由于你的初始资本为 0,你尽可以从 0 号项目开始。
在完成后,你将获得 1 的利润,你的总资本将变为 1。
此时你可以选择开始 1 号或 2 号项目。
由于你最多可以选择两个项目,所以你需要完成 2 号项目以获得最大的资本。
因此,输出最后最大化的资本,为 0 + 1 + 3 = 4。
解(java语言):
/**
* 1.新建一个数组,每个元素存放成本和利润。
* 2.将这个数组根据成本的大小生成一个小根堆。
* 3.只要花费比资金W低的依次从小根堆弹出(就是弹出当前资金可以购买的所有项目)
* 4.将弹出的元素放入一个大根堆(根据利润大小排序)中(即为了获取当前资金可以获得的最大利润)
* 5.从大根堆中取利润最大的元素
*/
class Solution {
public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {
Node[] arr = new Node[Profits.length];
for(int i = 0; i < arr.length; i++){
arr[i] = new Node(Profits[i], Capital[i]);
}
//java自带的堆,根据成本大小排序,成本小的在前面
PriorityQueue<Node> minCost = new PriorityQueue<>(new MinCostCompare());
//根据利润大小生成的大根堆,利润大的在前面
PriorityQueue<Node> maxProfit = new PriorityQueue<>(new MaxProfitCompare());
//将所有元素添加到根据成本大小排序的小根堆中
for(int i = 0; i < arr.length; i++){
minCost.add(arr[i]);
}
for(int i = 0; i < k; i++){
//将小根堆中所有比资金W小的.peek方法用于获取堆顶元素
while(!minCost.isEmpty() && minCost.peek().cost <= W){
maxProfit.add(minCost.poll());
}
//如果大根堆为空,即表示当前的资金没有可购买的项目,直接返回
if(maxProfit.isEmpty()){
return W;
}
//投资了获得最大利润的项目后资金为当前资金+利润
W += maxProfit.poll().profit;
}
return W;
}
}
class Node{
//利润
int profit;
//成本
int cost;
public Node(int profit, int cost){
this.profit = profit;
this.cost = cost;
}
}
/**
* 比较器,比较成本的大小
*/
class MinCostCompare implements Comparator<Node>{
@Override
public int compare(Node n1, Node n2){
return n1.cost - n2.cost;
}
}
/**
* 比较器,比较利润的大小
*/
class MaxProfitCompare implements Comparator<Node>{
@Override
public int compare(Node n1, Node n2){
return n2.profit - n1.profit;
}
}