You are given a 2D integer array intervals, where intervals[i] = [li, ri, weighti]. Interval i starts at position li and ends at ri, and has a weight of weighti. You can choose up to 4 non-overlapping intervals.
The score of the chosen intervals is defined as the total sum of their weights.
Return the lexicographically smallest array of at most 4 indices from
intervals with maximum score, representing your choice of non-overlapping intervals.
Two intervals are said to be non-overlapping if they do not share any points. In particular, intervals sharing a left or right boundary are considered overlapping.
Input: intervals =[[1,3,2],[4,5,2],[1,5,5],[6,9,3],[6,7,1],[8,9,1]]Output: [2,3]Explanation:
You can choose the intervals with indices 2, and 3with respective weights of
5, and 3.
Input: intervals =[[5,8,1],[6,7,7],[4,7,3],[9,10,6],[7,8,2],[11,14,3],[3,5,5]]Output: [1,3,5,6]Explanation:
You can choose the intervals with indices 1,3,5, and 6with respective
weights of 7,6,3, and 5.
This is a variant of the weighted interval scheduling problem, but we can select at most 4 non-overlapping intervals. We sort intervals by end time, and for each interval, use DP to track the best score for up to 4 picks. To find the last non-overlapping interval, we use binary search.
classSolution:
defmaxWeight(self, intervals: list[list[int]]) -> list[int]:
n = len(intervals)
arr = sorted([(r, l, w, i) for i, (l, r, w) in enumerate(intervals)])
ends = [r for r, l, w, i in arr]
dp = [[0]*5for _ in range(n+1)]
idx = [[[] for _ in range(5)] for _ in range(n+1)]
for i in range(1, n+1):
for k in range(1, 5):
l = bisect.bisect_left(ends, arr[i-1][1])
if dp[i-1][k] > dp[l][k-1] + arr[i-1][2]:
dp[i][k] = dp[i-1][k]
idx[i][k] = idx[i-1][k][:]
elif dp[i-1][k] < dp[l][k-1] + arr[i-1][2]:
dp[i][k] = dp[l][k-1] + arr[i-1][2]
idx[i][k] = idx[l][k-1][:] + [arr[i-1][3]]
else:
a = idx[i-1][k][:]
b = idx[l][k-1][:] + [arr[i-1][3]]
if a < b:
dp[i][k] = dp[i-1][k]
idx[i][k] = a
else:
dp[i][k] = dp[l][k-1] + arr[i-1][2]
idx[i][k] = b
best =0 ans = []
for k in range(1, 5):
if dp[n][k] > best:
best = dp[n][k]
ans = idx[n][k][:]
elif dp[n][k] == best and (not ans or idx[n][k] < ans):
ans = idx[n][k][:]
ans.sort()
return ans