Maximum Number of Events That Can Be Attended II

hard dp binary search sorting

Problem

Pick at most k of n events with start/end/value so no two overlap (any shared day disallowed); maximize total value.

Inputevents = [[1,2,4],[3,4,3],[2,3,1]], k = 2
Output7
Attend events 0 and 1 → 4 + 3 = 7.

from bisect import bisect_left
def max_value(events, k):
    events.sort(key=lambda e: e[1])
    n = len(events)
    starts = [e[0] for e in events]
    # for each i, next_idx = smallest j with events[j][0] > events[i][1]
    nxt = [bisect_left(starts, events[i][1] + 1) for i in range(n)]
    dp = [[0] * (k + 1) for _ in range(n + 1)]
    # iterate i from n-1 down
    for i in range(n - 1, -1, -1):
        for j in range(1, k + 1):
            dp[i][j] = max(dp[i+1][j], events[i][2] + dp[nxt[i]][j-1])
    return dp[0][k]
function maxValue(events, k) {
  events.sort((a, b) => a[1] - b[1]);
  const n = events.length;
  const starts = events.map(e => e[0]);
  function bsl(t) { let lo = 0, hi = n; while (lo < hi) { const m = (lo + hi) >> 1; if (starts[m] < t) lo = m + 1; else hi = m; } return lo; }
  const dp = Array.from({length: n + 1}, () => new Array(k + 1).fill(0));
  for (let i = n - 1; i >= 0; i--) {
    const nxt = bsl(events[i][1] + 1);
    for (let j = 1; j <= k; j++) {
      dp[i][j] = Math.max(dp[i+1][j], events[i][2] + dp[nxt][j-1]);
    }
  }
  return dp[0][k];
}
class Solution {
    public int maxValue(int[][] events, int k) {
        Arrays.sort(events, (a, b) -> a[1] - b[1]);
        int n = events.length;
        int[] starts = new int[n]; for (int i = 0; i < n; i++) starts[i] = events[i][0];
        int[][] dp = new int[n + 1][k + 1];
        for (int i = n - 1; i >= 0; i--) {
            int t = events[i][1] + 1, lo = 0, hi = n;
            while (lo < hi) { int m = (lo + hi) >> 1; if (starts[m] < t) lo = m + 1; else hi = m; }
            for (int j = 1; j <= k; j++)
                dp[i][j] = Math.max(dp[i+1][j], events[i][2] + dp[lo][j-1]);
        }
        return dp[0][k];
    }
}
int maxValue(vector<vector<int>>& events, int k) {
    sort(events.begin(), events.end(), [](auto& a, auto& b){ return a[1] < b[1]; });
    int n = events.size();
    vector<int> starts(n); for (int i = 0; i < n; i++) starts[i] = events[i][0];
    vector<vector<int>> dp(n + 1, vector<int>(k + 1, 0));
    for (int i = n - 1; i >= 0; i--) {
        int t = events[i][1] + 1, lo = 0, hi = n;
        while (lo < hi) { int m = (lo + hi) >> 1; if (starts[m] < t) lo = m + 1; else hi = m; }
        for (int j = 1; j <= k; j++)
            dp[i][j] = max(dp[i+1][j], events[i][2] + dp[lo][j-1]);
    }
    return dp[0][k];
}
Time: O(n·k·log n) Space: O(n·k)