题目:
给你两个数组,costs和profit是,第一个数组表示每个项目所花费的钱数,第二个数组表示每个项目所能挣得的利润。k表示你不能并行、只能串行的最多 做k个项
目 m表示你初始的资金 说明:你每做完一个项目,马上获得的收益,可以支持你去做下 一个 项目。 输出: 你最后获得的最大钱数。
解题思路:
首先,我们把这些项目都当作一个一个的节点,分别有两个属性,花费和利润。然后建两个堆,一个是按照花费从小到大的小根堆,还有一个是按照收益从大到小的大根堆,然后每做一个项目的时候,都把小根堆里花费小于当前所拥有钱的节点都弹出,进入大根堆,然后再从大根堆里找到收益最大的项目节点弹出,做这个项目,直到做完K个项目,或者当前所拥有的钱不足以再接着做项目了。
代码如下:
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 < nodes.length; i++) {
minCostQ.add(nodes[i]);
}
for (int i = 0; i < k; i++) {
while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) { //W是初始资金
maxProfitQ.add(minCostQ.poll());
}
if (maxProfitQ.isEmpty()) {
return W;
}
W += maxProfitQ.poll().p;
}
return W;
}
}