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