题目
假设 力扣(LeetCode)即将开始 IPO 。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目。帮助 力扣 设计完成最多 k 个不同项目后得到最大总资本的方式。
给你 n 个项目。对于每个项目 i ,它都有一个纯利润 profits[i] ,和启动该项目需要的最小资本 capital[i] 。
最初,你的资本为 w 。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。
总而言之,从给定项目中选择 最多 k 个不同项目的列表,以 最大化最终资本 ,并输出最终可获得的最多资本。
示例
示例1
输入:k = 2, w = 0, profits = [1,2,3], capital = [0,1,1]
输出:4
解释:
由于你的初始资本为 0,你仅可以从 0 号项目开始。
在完成后,你将获得 1 的利润,你的总资本将变为 1。
此时你可以选择开始 1 号或 2 号项目。
由于你最多可以选择两个项目,所以你需要完成 2 号项目以获得最大的资本。
因此,输出最后最大化的资本,为 0 + 1 + 3 = 4。
示例2
输入:k = 3, w = 0, profits = [1,2,3], capital = [0,1,2]
输出:6
关键思路
考虑贪心策略,即每轮投资时,选取当前利润最大的项目。
想象我们自身在投资时的情况,会先根据当前拥有资本,选出可以投资的项目,再根据项目的利润情况,选取能够获取最大利润的项目。
在循环开始前,我们需要维护一个选项列表,这个列表用于存放每轮可以投资的项目及其利润。在每次循环中,需要将可以投资的项目及其利润存入这个列表,再根据利润大小对项目进行排序,选取利润最大的项目进行投资。
例如,对于k = 2, w = 0, profits = [1,2,3], capital = [0,1,1]:
第1轮投资:
当前资本为0,将所需资本为0的项目放入选项列表中。
选项列表中存在(1)所需资本为0,利润为1的项目。
考虑投资项目(1),获得利润为1,最终资本为1。
删除选项列表中的已投资项目信息。
第2轮投资:
当前资本为1,将所需资本为1的项目放入选项列表中。
选项列表中存在(1)所需资本为1,利润为2的项目;(2)所需资本为1,利润为3的项目。
考虑投资项目(2),获得利润为3,最终资本为4。
同时删除选项列表中的已投资项目信息。
2轮投资结束:
最终资本为4。
代码实现
class Solution(object):
def findMaximizedCapital(self, k, w, profits, capital):
"""
:type k: int
:type w: int
:type profits: List[int]
:type capital: List[int]
:rtype: int
"""
alternatives = [] # set
for i in range(k): # investments
for j in range(len(capital)):
if w>=capital[j]: # if qualified
alternatives.append([profits[j], capital[j]]) # add it to alternatives
capital[j] = float("inf")
alternatives.sort(key=lambda x:x[0], reverse=False) # sort alternatives by profits
invest = alternatives.pop() # best
w = w + invest[0] # gain profits
return w
if __name__ == "__main__":
k = input()
w = input()
profits = input()
capital = input()
obj = Solution()
result = obj.findMaximizedCapital(k, w, profits, capital)
print(result)
运行结果
4
6