力扣 502. IPO 动态规划(超时) + 贪心

博客探讨了力扣502题的动态规划和贪心算法两种解法。动态规划虽然导致超时,而贪心算法通过使用堆实现了高效解决方案,执行时间为92ms,击败了大部分Python3提交。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 动态规划

dp[i][j]表示前i个项目中做j个项目带来的最大收益
需要先对所有的项目按照启动资本排序
但是结果超时了:32 / 35 个通过测试用例

class Solution:
    def findMaximizedCapital(self, k: int, w: int, profits: List[int], capital: List[int]) -> int:
        n = len(profits)
        tasks = [(capital[i], profits[i]) for i in range(n)]
        tasks.sort(key=lambda x: x[0])
        # dp[i][j]表示前i个项目中做j个项目带来的最大收益
        dp, max_first = [[0] * (k + 1) for _ in range(n + 1)], 0
        # 初始化k为1的dp数组:从前i个项目中做1个项目带来的最大收益——要挑能负担的起,且利润最大的那个项目
        for i in range(n):
            if w >= tasks[i][0] and max_first < tasks[i][1]:
                max_first = tasks[i][1]
            dp[i + 1][1] = max_first

        for ki in range(2, k + 1):
            for i in range(1, n + 1):
                # 只能从前i个项目中选,如果需要选出的数量已经超过候选的项目数,则无项目可选,不能继续扩大利润
                if i < ki:
                    dp[i][ki] = dp[i][ki - 1]
                else:
                    # 如果从前i-1个项目中,选择ki-1个,获得的最大收益,加上初始资本,足以支付当前项目(第i-1个)的成本
                    if w + dp[i - 1][ki - 1] >= tasks[i - 1][0]:
                        dp[i][ki] = max(dp[i - 1][ki - 1] + tasks[i - 1][1], dp[i - 1][ki])
                    else:
                        dp[i][ki] = dp[i - 1][ki]

        return w + dp[n][k]

2 贪心+堆

实际上也确实没必要用动规,这道题可以直接上贪心:每次都从可选的范围内选择利润最大的task即可

执行用时:92 ms, 在所有 Python3 提交中击败了99.33% 的用户
内存消耗:35.3 MB, 在所有 Python3 提交中击败了54.67% 的用户
通过测试用例:35 / 35

class Solution:
    def findMaximizedCapital(self, k: int, w: int, profits: List[int], capital: List[int]) -> int:
        if w >= max(capital):
            return w + sum(heapq.nlargest(k, profits))

        n = len(profits)
        curr = 0
        tasks = [(capital[i], profits[i]) for i in range(n)]
        tasks.sort(key=lambda x: x[0])

        pq = []
        # 贪心,每次取能负担的起的最大利润的项目,一共取k次
        for _ in range(k):
            # 每一轮挑选项目,都先根据当前已经更新(增加)了的w,把(增加了资本以后)能负担的起的项目(的利润)依次(已经排序)入堆
            while curr < n and tasks[curr][0] <= w:
                # Python不支持大根堆,所以取相反数,用小根堆替代大根堆
                heapq.heappush(pq, -tasks[curr][1])
                curr += 1
            if pq:
                # 当前队列里还有可选的项目。堆里是利润的相反数,所以这里要减去
                w -= heapq.heappop(pq)
            else:
                # 当前队列里已无项目可选
                break

        return w
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值