Maximum Profit in Job Scheduling
Jobs have start, end, profit. Pick non-overlapping jobs maximizing total profit (touching endpoints allowed).
Intuition
Sort jobs by end time and ask, per job: take it or skip it? Skipping inherits the best so far. Taking it earns its profit plus the best achievable among jobs that finish by its start — and because ends are sorted, that predecessor is found by binary search. Weighted intervals break plain greedy; this DP + bisect handles the weights.
Approach
Sort by end time
dp is built in end-time order: dp[i] = best profit using the first i jobs. dp[0] = 0.
Take or skip
dp[i+1] = max(dp[i] / skip /, profit_i + dp[k] / take /), where k = number of jobs ending ≤ start_i — found with bisect_right on the sorted end array.
Why greedy fails here
Unweighted interval scheduling is greedy-solvable, but one fat job can beat many thin ones (or vice versa) — profits force trying both branches, which the DP does in O(log n) per job.
Solution & live demo
Edge cases
end ≤ start counts as compatible — bisect_right includes it.
dp keeps the single most profitable one.
dp = [0, profit].