Each interval has a value; select non-overlapping intervals maximising the total. Greedy fails here — this is a DP.

The algorithm —

Sort by finish time. For each interval , let be the last interval that finishes at or before starts (found by binary search).

— skip interval , or take it and jump back to .

long long weightedIntervalScheduling(vector<array<long long,3>> iv) {   // {start, end, value}
    int n = iv.size();
    sort(iv.begin(), iv.end(), [](auto& a, auto& b){ return a[1] < b[1]; });
 
    vector<long long> ends(n);
    for (int i = 0; i < n; i++) ends[i] = iv[i][1];
 
    vector<long long> dp(n + 1, 0);
    for (int i = 0; i < n; i++) {
        int p = upper_bound(ends.begin(), ends.begin() + i, iv[i][0]) - ends.begin();
        dp[i + 1] = max(dp[i], iv[i][2] + dp[p]);
    }
    return dp[n];
}

Use upper_bound for half-open intervals (touching is allowed) and lower_bound when touching conflicts — the same convention question as in interval scheduling.

Why greedy fails

By value: one huge interval may block several that together are worth more. By value density: same problem. By finish time: ignores the values entirely.

The DP is necessary because the choice at each interval depends on the best achievable before it, which greedy cannot know.

Reconstruction

vector<int> chosen;
int i = n;
while (i > 0) {
    int j = i - 1;
    if (dp[i] == dp[i-1]) i--;                             // interval j was skipped
    else { chosen.push_back(j); i = p[j]; }                // taken
}
reverse(chosen.begin(), chosen.end());

Store the values during the forward pass to avoid recomputing them.

Variants

VariantMethodCost
Unweighted (max count)greedy by finish time
Weightedthis DP
At most intervalsdp[i][k]
machines (parallel)min-cost flow
Intervals on a circlefix one interval as included/excluded;
With setup times between intervalsadjust
Maximise the count, tie-break by weightDP on a pair
Value depends on when it is scheduledmore general DP

machines

With parallel machines, greedy and the simple DP both break. Model as min-cost flow: a path along the time axis with capacity , plus an arc for each interval from its start time to its end time with capacity 1 and cost . A min-cost flow of value selects the optimal set.

This “intervals as arcs over a time line with capacity ” construction is a genuinely reusable modelling pattern.

Generalisation: DP over a sorted axis

The structure — sort by one coordinate, binary search the last compatible predecessor, take the max — appears throughout:

ProblemThe “predecessor”
Weighted interval schedulinglast interval finishing before this starts
LIS with weightslast smaller element
Longest chain of pairslast compatible pair
Box stacking / Russian dollslast fitting box
Job sequencing with deadlinessee that page
Maximum sum of non-adjacent elementsindex

When the predecessor is monotone, the binary search can be replaced by a two-pointer, giving after the sort.

See also: Interval Scheduling · Introduction to DP · Min-Cost Flow