题目
输入:
参数1,正数数组costs 参数2,正数数组profits 参数3,正数k 参数4,正数m
costs[i]表示i号项目的花费
profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润)
k表示你不能并行、只能串行的最多做k个项目
m表示你初始的资金
说明:
你每做完一个项目,马上获得的收益,可以支持你去做下一个项目。
输出:
你最后获得的最大钱数。
实现思路
按照贪心策略 首先我们根据给定的初始基金可以找到我们能做的项目,之后得找到这些能做的项目中利润最高的,算上花费之后的利润我们又可以去找我们能做的其他项目,之后操作一样。
具体实现:
1.构建两个优先队列。一个是按照基金的构造小根堆,一个是按照利润构造的大根堆
2.将所有元素构建成对象利用比较器进行相应的构建堆的过程
3.将所有对象加入基金小根堆
4.如果基金小根堆里的基金小于等于我们给定的初始基金,将其弹出并加入利润大根堆中。
5.此时利润大根堆中一定就是我们需要的利润最高的解,累加利润并弹出。
6.重复4步骤 直到找到了k个解
代码
/**
* @description: IPO问题–获得最大收益
* @Author MRyan
* @Date 2020/6/12 19:26
* @Version 1.0
*/
/**
* 实现思路: 按照贪心策略 首先我们根据给定的初始基金可以找到我们能做的项目,之后得找到这些能做的项目中利润最高的,算上花费之后的利润我们又可以去找我们能做的其他项目,之后操作一样。
* 具体实现:
* 1.构建两个优先队列。一个是按照基金的构造小根堆,一个是按照利润构造的大根堆
* 2.将所有元素构建成对象利用比较器进行相应的构建堆的过程
* 3.将所有对象加入基金小根堆
* 4.如果基金小根堆里的基金小于等于我们给定的初始基金,将其弹出并加入利润大根堆中。
* 5.此时利润大根堆中一定就是我们需要的利润最高的解,累加利润并弹出。
* 6.重复4步骤 直到找到了k个解
*/
public class code_11 {
public static void main(String[] args) {
List<CP> lists = new ArrayList<>();
lists.add(new CP(3, 9));
lists.add(new CP(6, 20));
lists.add(new CP(8, 14));
lists.add(new CP(100, 200));
int answer = answer(lists, 3, 40);
System.out.println(answer);
}
/**
* @param lists
* @param k 只能做4个项目
* @param m 初始资金
*/
private static int answer(List<CP> lists, int k, int m) {
int mm = m;
//按初始基金构建小根堆
PriorityQueue<CP> queueConst = new PriorityQueue<>(new CompareConst());
//按利润构建大根堆
PriorityQueue<CP> queueProfit = new PriorityQueue<>(new COmpareProfit());
for (CP cp : lists) {
queueConst.add(cp);
}
//当queueConst中有小于等于初始基金时弹出放入queueProfit中
//只取k个最优解
while (k > 0) {
while ((queueConst.peek()).cost <= mm) {
queueProfit.add(queueConst.poll());
}
//防止空指针
if (queueProfit.isEmpty() || queueConst.isEmpty()) {
break;
}
//输出测试
CP text = queueProfit.peek();
//现有的算上利润的钱 纯利润
mm += text.profit;
System.out.println("const: " + text.cost + " profit: " + text.profit + " now Money: " + mm);
queueProfit.poll();
k--;
}
return mm;
}
/**
* 按照初始基金构造小根堆结构 初始资金小的在堆顶
*/
private static class CompareConst implements Comparator<CP> {
@Override
public int compare(CP cp1, CP cp2) {
if (cp1.cost < cp2.cost) {
return -1;
} else if (cp1.cost > cp2.cost) {
return 1;
} else {
return 0;
}
}
}
/**
* 按照利润构造大根堆结构 利润最高的在堆顶
*/
private static class COmpareProfit implements Comparator<CP> {
@Override
public int compare(CP cp1, CP cp2) {
if (cp1.profit < cp2.profit) {
return 1;
} else if (cp1.profit > cp2.profit) {
return -1;
} else {
return 0;
}
}
}
public static class CP {
//初始资金
private int cost;
//获得利润
private int profit;
public CP(int cost, int profit) {
this.cost = cost;
this.profit = profit;
}
}
}