Given n jobs with start time, end time, and profit, find the maximum profit for non-overlapping jobs.
I:
start_time = [1, 2, 3, 3]
end_time = [3, 4, 5, 6]
profit = [50, 10, 40, 70]
O: 120
I:
startTime = [1, 2, 3, 4, 6]
endTime = [3, 5, 10, 6, 9]
profit = [20, 20, 100, 70, 60]
O: 150
A simple exchange greedy argument is not enough because the weight is hard to swap
dp: {1: 0, 2: 0, 3: 20, 4: 20, 5: 20, 6: 90, 9: 150, 10: 150}
def jobScheduling(
self, startTime: List[int], endTime: List[int], profit: List[int]
) -> int:
Event = namedtuple('Event', ['time', 'is_start', 'job_id'])
events: List[Event] = []
dp: Dict[int, int] = {}
for i in range(len(startTime)):
dp[startTime[i]] = 0
start_event = Event(startTime[i], True, i)
events.append(start_event)
dp[endTime[i]] = 0
end_event = Event(endTime[i], False, i)
events.append(end_event)
sorted_events = sorted(events, key=lambda e: e.time)
# init
last_profit = 0
# topo sort is time order
for event in sorted_events:
if event.is_start:
dp[event.time] = max(dp[event.time], last_profit)
else:
# choose or not choose this interval
dp[event.time] = max(
dp[event.time],
dp[startTime[event.job_id]] + profit[event.job_id],
last_profit
)
last_profit = dp[event.time]
return last_profit