Problem of The Day: Minimum Difficulty of a Job Schedule
Problem Statement
notes:
- Very hard problem
- Need to review later
Solution
class Solution:
def minDifficulty(self, jobDifficulty: List[int], d: int) -> int:
n = len(jobDifficulty)
if n < d:
return -1
hardest_job_remaining = [0] * n
hardest_job = 0
for i in range(n - 1, -1, -1):
hardest_job = max(hardest_job, jobDifficulty[i])
hardest_job_remaining[i] = hardest_job
@cache
def dp(i, remain_days):
if remain_days == 1:
return hardest_job_remaining[i]
res = float("inf")
curr_hardest = 0
for j in range(i, n - (remain_days - 1)):
curr_hardest = max(curr_hardest, jobDifficulty[j])
res = min(res, curr_hardest + dp(j + 1, remain_days - 1))
return res
return dp(0, d)
Editorial
Top down approach
class Solution:
def minDifficulty(self, jobDifficulty: List[int], d: int) -> int:
n = len(jobDifficulty)
# If we cannot schedule at least one job per day,
# it is impossible to create a schedule
if n < d:
return -1
hardest_job_remaining = [0] * n
hardest_job = 0
for i in range(n - 1, -1, -1):
hardest_job = max(hardest_job, jobDifficulty[i])
hardest_job_remaining[i] = hardest_job
@lru_cache(None)
def dp(i, day):
# Base case, it's the last day so we need to finish all the jobs
if day == d:
return hardest_job_remaining[i]
best = float("inf")
hardest = 0
# Iterate through the options and choose the best
for j in range(i, n - (d - day)): # Leave at least 1 job per remaining day
hardest = max(hardest, jobDifficulty[j])
best = min(best, hardest + dp(j + 1, day + 1)) # Recurrence relation
return best
return dp(0, 1)
Bottom up approach
class Solution:
def minDifficulty(self, jobDifficulty: List[int], d: int) -> int:
n = len(jobDifficulty)
# If we cannot schedule at least one job per day,
# it is impossible to create a schedule
if n < d:
return -1
dp = [[float("inf")] * (d + 1) for _ in range(n)]
# Set base cases
dp[-1][d] = jobDifficulty[-1]
# On the last day, we must schedule all remaining jobs, so dp[i][d]
# is the maximum difficulty job remaining
for i in range(n - 2, -1, -1):
dp[i][d] = max(dp[i + 1][d], jobDifficulty[i])
for day in range(d - 1, 0, -1):
for i in range(day - 1, n - (d - day)):
hardest = 0
# Iterate through the options and choose the best
for j in range(i, n - (d - day)):
hardest = max(hardest, jobDifficulty[j])
# Recurrence relation
dp[i][day] = min(dp[i][day], hardest + dp[j + 1][day + 1])
return dp[0][1]