5639. 完成所有工作的最短时间

Leetcode 周赛223的hard题目,此题是我见到的很惊艳的题目,用到了二进制表示状态,枚举状态,二分法,动态规划等知识,值得记录一下。

看到这个题目时,只能想到二分法,看了题解后才发现这个是二分 + 状压dp的题目。

看了题解,发现这个题目的实现用了很多二进制表示,其中最为精辟的是枚举状态,结合https://oi-wiki.org/math/bit/#_14勉强看懂代码。

下面是python3的代码实现,但是tle了,看了下面的评论说是此题对python不友好,下次再用C++把这个题目实现一下吧。

class Solution:
    def minimumTimeRequired(self, jobs: List[int], k: int) -> int:
        n = len(jobs)
        tot = [0] * (1 << n)
        for i in range(1, 1 << n):
            for j in range(n):
                if i & (1 << j) == 0:
                    continue
                tot[i] = jobs[j] + tot[i - (1 << j)]
                break
        mmax, summ = 0, 0
        for item in jobs:
            mmax = max(mmax, item)
            summ += item
        l, r = mmax, summ
        while l < r:
            mid = (l + r) // 2
            dp = [float('inf')] * (1 << n)
            dp[0] = 0
            for i in range(1, 1 << n):
                s = i
                while s:
                    if tot[s] <= mid:
                        dp[i] = min(dp[i], dp[i - s] + 1)
                    s = (s - 1) & i
            if dp[(1 << n) - 1] <= k:
                r = mid
            else:
                l = mid + 1
        return l
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值