题目:
给出N个任务需要执行的时间,以及执行机构连续工作的时间,输出最少需要执行几次“连续工作”
题解:
- 方法一:模拟+剪枝
用 S(m) 表示,已安排 0~m 个任务,所有的安排情况(是个集合,集合每个元素,是各session已用时间)
在安排 第 m+1 个任务的时候,就在所有安排情况(即集合每个元素)中,尝试所有安排 m+1 的可能性
模拟所有可能的情况,时间复杂度为,这是最坏情况
采取如下剪枝:
1-先安排时间长的任务:开头的时候安排情况可能性就少,后面发散的少
2-如果恰好凑成 sessionTime,存在最优解,其它情况不再保留了
3-所有安排情况,排序后加入集合,去重
这些剪枝用下来,最优情况是 ,一般情况会稍多一点,不会多太多
- 方法二:状态压缩动态规划
DP[m] 表示,m 状态下最少 session 数。m 是位图,表示每一个任务是否安排
状态转移:
时间复杂度,大约
源码:
方法一:模拟+剪枝
56ms,15.6MB
class Solution:
def findindex(a, m):
for (i, n) in enumerate(a):
if n <= m:
return i
def minSessions(self, tasks: list[int], sessionTime: int) -> int:
tasks.sort(reverse=True)
ans = {(tasks[0],)}
for i in range(1, len(tasks)):
t = tasks[i]
newans = set()
for p in ans:
p = list(p)
index = Solution.findindex(p, sessionTime - t)
if index == None:
# 只能新开一个 session
p.append(t)
newans.add(tuple(p))
elif p[index] == sessionTime - t:
# 恰好有一个 session 刚好用完
p[index] = sessionTime
p.sort(reverse=True)
newans.add(tuple(p))
else:
# 其它情况,要遍历所有可能性了
for i in range(index, len(p)):
pp = p.copy()
pp[i] += t
pp.sort(reverse=True)
newans.add(tuple(pp))
p.append(t)
p.sort(reverse=True)
newans.add(tuple(p))
ans = newans
return min(len(p) for p in ans)
if __name__ == "__main__":
print(Solution().minSessions(tasks = [1,2,3], sessionTime = 3))
print(Solution().minSessions(tasks = [3,1,3,1,1], sessionTime = 8))
print(Solution().minSessions(tasks = [1,2,3,4,5], sessionTime = 15))
print(Solution().minSessions([2,3,3,4,4,4,5,6,7,10], 12))
print(Solution().minSessions([1,2,2,3,4,5,6,6,7,8,8,8],15))
方法二:状态压缩动态规划
3904ms,15.4MB
class Solution:
def minSessions(self, tasks: list[int], sessionTime: int) -> int:
n = len(tasks)
cost = [0] * (1 << n)
for i in range(1, 1 << n):
cost[i] = sum(tasks[x] for x in range(n) if (1<<x) & i)
dp = [float('inf')] * (1 << n)
dp[0] = 0
for i in range(1, 1 << n):
j = i
while j:
if cost[j] <= sessionTime:
dp[i] = min(dp[i], dp[i - j] + 1)
j = (j - 1) & i
return dp[-1]
if __name__ == "__main__":
print(Solution().minSessions(tasks = [1,2,3], sessionTime = 3))
print(Solution().minSessions(tasks = [3,1,3,1,1], sessionTime = 8))
print(Solution().minSessions(tasks = [1,2,3,4,5], sessionTime = 15))
print(Solution().minSessions([2,3,3,4,4,4,5,6,7,10], 12))
print(Solution().minSessions([1,2,2,3,4,5,6,6,7,8,8,8],15))