您希望在d天内安排作业列表。作业是相关的(即,要处理第i个作业,必须完成所有作业j,其中0<;=j<;i)
你必须每天至少完成一项任务。作业计划的难度是d天中每天的难度总和。一天的难度是当天完成工作的最大难度
给定一个整数数组和一个整数d。第i个作业的难度是作业难度[i]
返回作业计划的最小难度。如果找不到作业的时间表,请返回-1
Input: jobDifficulty = [6,5,4,3,2,1], d = 2
Output: 7
Explanation: First day you can finish the first 5 jobs, total difficulty = 6.
Second day you can finish the last job, total difficulty = 1.
The difficulty of the schedule = 6 + 1 = 7
对于上述问题,我有以下解决方案:
from functools import lru_cache
class Solution:
def minDifficulty(self, jobDifficulty: List[int], d: int) -> int:
@lru_cache(None)
def oneDayDifficulty(start, end):
if start + 1 == end:
return jobDifficulty[start]
mid = (start + end) // 2
return max(oneDayDifficulty(start, mid), oneDayDifficulty(mid, end))
@lru_cache(None)
def dp(nextTask, days):
if days == 1:
return oneDayDifficulty(0, nextTask)
res = float("inf")
for startTask in range(days - 1, nextTask):
res = min(res, dp(startTask, days - 1) + oneDayDifficulty(startTask, nextTask))
return res
res = dp(len(jobDifficulty), d)
return -1 if res == float('inf') else res
我不确定时间和空间的复杂性是什么,它会是O(d*n^2)吗? 你有更好的办法解决这个问题吗
我们可以有
O(d * n * log n)
。让dp[i][d]
代表分配给第d
天的第i
个任务的最佳选择。然后:我们可以将迄今为止看到的所有
dp[j][d]
存储在按A[j]
排序的二叉搜索树中,并添加了与左子树中的任何节点关联的最小dp[j-1][d-1]
和与右子树中的任何节点关联的A[j] + dp[j-1][d-1]
的修饰;与它配对的j
一起。当我们到达A[i]
时,我们查找它在树中的位置,跟踪与高于它的任何节点关联的最小A[j] + dp[j-1][d-1]
,以及与等于或低于它的任何节点关联的最小dp[j-1][d-1]
。那么我们的选择就变成了:在
O(log n)
中插入、更新装饰并在树中查找,我们对每个d
执行O(n)
次时间复杂度由รยקคгรђשค
我们可以在
O(d*N)
时间复杂度中使用O(N)
空间,使用堆栈说明:
dp配方:
这个公式与here几乎没有什么不同。因为我们可以使用堆栈计算到目前为止在当天
d
发现的最大难度的成本重复性:
有3种情况:
ith
作业是d天的唯一作业,其余所有作业在{A[i]
是否比当前已完成的任何先前更高难度的工作j
难度更大d
j
我们在今天前面看到的d
李>C++实现:
我们维护堆栈以计算迄今为止所看到的最高难度作业
j
。正如我们在递归中看到的,我们只需要前一天的值来计算当天的值,所以我们在那里节省了空间时间复杂性:
对于每一天,我们都要花费
O(N)
时间来计算。所以时间复杂度是O(d*N)
。堆栈中的项最多被推送和弹出O(N)
次额外空间复杂性:
O(N)
存储当前和以前的状态,以及O(N)
存储堆栈相关问题 更多 >
编程相关推荐