-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathmaximum-profit-in-job-scheduling.py
74 lines (55 loc) · 2.31 KB
/
maximum-profit-in-job-scheduling.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import heapq
from typing import List, Tuple
from functools import lru_cache
class Solution:
def jobScheduling(
self, start_times: List[int], end_times: List[int], profits: List[int]
) -> int:
assert len(start_times) == len(end_times)
dp_left: List[Tuple[int, int]] = [] # [(-profit, job)]
dp_right: List[Tuple[int, int, int]] = [] # [(end_time, profit, job)]
max_profit = 0
for job in sorted(range(len(profits)), key=lambda job: start_times[job]):
while dp_right and dp_right[0][0] <= start_times[job]:
_, tmp_profit, tmp_job = heapq.heappop(dp_right)
heapq.heappush(dp_left, (-tmp_profit, tmp_job))
profit = profits[job] + (-dp_left[0][0] if dp_left else 0)
max_profit = max(max_profit, profit)
heapq.heappush(dp_right, (end_times[job], profit, job))
return max_profit
def jobSchedulingBottomUpN2(
self, start_times: List[int], end_times: List[int], profits: List[int]
) -> int:
assert len(start_times) == len(end_times)
jobs_by_start = list(
sorted(range(len(profits)), key=lambda job: start_times[job])
)
jobs_by_end = list(sorted(range(len(profits)), key=lambda job: end_times[job]))
dp = [0] * len(start_times)
for job in jobs_by_start:
dp[job] = profits[job]
for prev_job in jobs_by_end:
if start_times[job] >= end_times[prev_job]:
dp[job] = max(dp[job], dp[prev_job] + profits[job])
else:
break
return max(dp)
def jobSchedulingTopDown(
self, start_times: List[int], end_times: List[int], profits: List[int]
) -> int:
assert len(start_times) == len(end_times)
start_times.append(0)
end_times.append(0)
profits.append(0)
jobs = list(zip(start_times, end_times, profits))
jobs.sort()
@lru_cache(None)
def dp(job: int, prev_job: int) -> int:
if job == len(jobs):
return 0
start_time, end_time, profit = jobs[job]
return max(
dp(job + 1, prev_job),
(dp(job + 1, job) + profit) if start_time >= jobs[prev_job][1] else 0,
)
return dp(1, 0)