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

你可能感兴趣的:(Leetcode,状压dp,二进制,二分法)