題目
輸入:
參數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;
}
}
}