输入: 参数1,正数数组costs 参数2,正数数组profits 参数3, 正数k 参数4,正数m
costs[i] 表示i号项目的花费
profits[i] 表示i号项目在扣除花费之后还能挣到的钱(利润) k表示你不能并行、只能串行的最多 做k个项目 m表示你初始的资金
说明:你每做完一个项目,马上获得的收益,可以支持你去做下 一个 项目。
输出: 你最后获得的最大钱数。
思路:
1、定义项目类如下:
class program:
def __init__(self,cost,profit):
self.cost = cost
self.profit = profit
2、生成小根堆costMinHeap, 可以把具体的program放进costMinHeap中,根据Program的花费来组织小根堆,花费最少的program放在costMinHeap的堆顶
3、生成大根堆profitMaxHeap, 可以把具体的program放进profitMaxHeap中,根据Program的利润来组织小根堆,利润最多的Program放在profitMaxHeap的堆顶
4、根据costs和profits数组,可以得到所有的program,把所有的program放进costMinHeap
5、根据当前的资金W,来解锁costMinHeap中的项目,只要是花费小于或等于W的项目,就从costMinHeap中弹出,放入profitMaxHeap。因为costMinHeap是小根堆,所以依次弹出program,知道costMinHeap为空或者剩下项目的花费都大于W,弹出过程停止。每一个从costMinHeap弹出的program,都进入profitMaxHeap。进入步骤6
6、profitMaxHeap装着所有可以被考虑和被解锁的项目
1)如果经历了步骤5之后,发现profitMaxHeap为空,首先说明当前资金W并没有解锁出任何项目,其次说明目前已经没有任何项目可以挑选啦,直接返回W
2)如果经历了步骤5解锁之后,发现profitMaxHeap不为空。选择位于profitMaxHeap堆顶的那个项目完成,标记为programBest,因为在所有可以被考虑的项目中,profitMaxHeap堆顶的项目一定是获得利润最多的项目。完成programBest之后,可以获得programBest的利润。所以W+=programBest.profit。然后重复步骤5,进行新一轮的解锁。
7、如果步骤6进行的过程中没有返回。那么做完K个项目后,返回W
"""伪代码如下"""
class Program:
def __init__(self,cost,profit):
self.cost = cost
self.profit = profit
def getMaxmoney(W,K,costs,profits):
if W < 1 or K < 0 or costs == None or profits == None or len(costs) != len(profits):
return W
"""
项目花费小根堆,花费最少的项目在顶部
"""
costMinHeap = CostMinHeap()
"""
项目利润大根堆,利润最大的项目在顶部
"""
profitMaxHeap = ProfitMaxHeap()
"""所有项目都进花费小根堆"""
for i in range(len(costs)):
costMinHeap.add(costs[i],profits[i])
"""依次做k个项目"""
for i in range(K+1):
"""当前资金为W,在项目花费小根堆里所有花费小于或等于W的项目,都可以考虑"""
while (!costMinHeap.isEmpty() and costMinHeap.peek().cost <= W):
"""把可以考虑的项目都放进项目利润大根堆里"""
profitMaxHeap.add(costMinHeap.poll())
"""如果此时项目利润大根堆为空,说明可以考虑的项目为空,说明当前资金W已经无法解锁任何项目,直接返回W"""
if (profitMaxHeap.isEmpty()):
return W
W += profitMaxHeap.poll().profit
return W