Learn DSA
Two Pointers
Sliding Window
Intervals
Stack
Linked List
Binary Search
Heap
Depth-First Search
Breadth-First Search
Backtracking
Graphs
Dynamic Programming
Greedy Algorithms
Trie
Prefix Sum
Matrices
Maximum Profit in Job Scheduling
DESCRIPTION (credit Leetcode.com)
Given three arrays, starts, ends, and profits, each representing the start time, end time, and profit of jobs respectively, your task is to schedule the jobs to maximize total profit. You can only work on one job at a time, and once a job has been started, you must finish it before starting another. The goal is to find the maximum profit that can be earned by scheduling jobs such that they do not overlap.
EXAMPLES
Input:
starts = [1, 3, 6, 9] ends = [4, 5, 10, 8] profits = [20, 20, 100, 70]
The optimal solution would schedule the jobs as follows:
Start the first job at time 1 and complete it by 4 for a profit of 20. Start the next job at time 5 and complete it by 10 for a profit of 100.
The total profit is 20 + 100 = 120
Run your code to see results here
Explanation
from bisect import bisect_rightdef job_scheduling(starts, ends, profits):jobs = sorted(zip(starts, ends, profits),key=lambda x: x[1])dp = [0] * (len(jobs) + 1)for i in range(1, len(dp) + 1):start, end, profit = jobs[i - 1]# find number of jobs to finish before start of current jobnum_jobs = bisect_right(jobs, start, key=lambda x: x[1])dp[i] = max(dp[i - 1], dp[num_jobs] + profit)return dp[-1]
from bisect import bisect_rightdef job_scheduling(starts, ends, profits):jobs = sorted(zip(starts, ends, profits),key=lambda x: x[1])dp = [0] * (len(jobs) + 1)for i in range(1, len(dp) + 1):start, end, profit = jobs[i - 1]# find number of jobs to finish before start of current jobnum_jobs = bisect_right(jobs, start, key=lambda x: x[1])dp[i] = max(dp[i - 1], dp[num_jobs] + profit)return dp[-1]
- We can schedule the current job, in which case the profit would be dp[num_jobs] + profit.
- We can skip the current job, in which case the profit would be dp[i - 1].
from bisect import bisect_rightdef job_scheduling(starts, ends, profits):jobs = sorted(zip(starts, ends, profits),key=lambda x: x[1])dp = [0] * (len(jobs) + 1)for i in range(1, len(dp) + 1):start, end, profit = jobs[i - 1]# find number of jobs to finish before start of current jobnum_jobs = bisect_right(jobs, start, key=lambda x: x[1])dp[i] = max(dp[i - 1], dp[num_jobs] + profit)return dp[-1]
Skipping the current job
- We can schedule the current job, in which case the profit would be dp[num_jobs] + profit = 0 + 18 = 18.
- We can skip the current job, in which case the profit would be dp[i - 1] = 20.
from bisect import bisect_rightdef job_scheduling(starts, ends, profits):jobs = sorted(zip(starts, ends, profits),key=lambda x: x[1])dp = [0] * (len(jobs) + 1)for i in range(1, len(dp) + 1):start, end, profit = jobs[i - 1]# find number of jobs to finish before start of current jobnum_jobs = bisect_right(jobs, start, key=lambda x: x[1])dp[i] = max(dp[i - 1], dp[num_jobs] + profit)return dp[-1]
Solution
from bisect import bisect_rightdef job_scheduling(starts, ends, profits):jobs = sorted(zip(starts, ends, profits),key=lambda x: x[1])dp = [0] * (len(jobs) + 1)for i in range(1, len(dp) + 1):start, end, profit = jobs[i - 1]# find number of jobs to finish before start of current jobnum_jobs = bisect_right(jobs, start, key=lambda x: x[1])dp[i] = max(dp[i - 1], dp[num_jobs] + profit)return dp[-1]
Complexity Analysis
- Time complexity: O(n * log n) due to the sorting of the jobs, and the binary search for each job.
- Space complexity: O(n) due to the dp array.
Loading comments...