1751. 最多可以参加的会议数目 II
难度困难69
给你一个 events
数组,其中 events[i] = [startDayi, endDayi, valuei]
,表示第 i
个会议在 startDayi
天开始,第 endDayi
天结束,如果你参加这个会议,你能得到价值 valuei
。同时给你一个整数 k
表示你能参加的最多会议数目。
你同一时间只能参加一个会议。如果你选择参加某个会议,那么你必须 完整 地参加完这个会议。会议结束日期是包含在会议内的,也就是说你不能同时参加一个开始日期与另一个结束日期相同的两个会议。
请你返回能得到的会议价值 最大和 。
示例 1:
输入:events = [[1,2,4],[3,4,3],[2,3,1]], k = 2
输出:7
解释:选择绿色的活动会议 0 和 1,得到总价值和为 4 + 3 = 7 。
示例 2:
输入:events = [[1,2,4],[3,4,3],[2,3,10]], k = 2
输出:10
解释:参加会议 2 ,得到价值和为 10 。
你没法再参加别的会议了,因为跟会议 2 有重叠。你 不 需要参加满 k 个会议。
示例 3:
输入:events = [[1,1,1],[2,2,2],[3,3,3],[4,4,4]], k = 3
输出:9
解释:尽管会议互不重叠,你只能参加 3 个会议,所以选择价值最大的 3 个会议。
提示:
1 <= k <= events.length
1 <= k * events.length <= 106
1 <= startDayi <= endDayi <= 109
1 <= valuei <= 106
动态规划
题解:https://leetcode.cn/problems/maximum-number-of-events-that-can-be-attended-ii/solution/po-su-dp-er-fen-dp-jie-fa-by-ac_oier-88du/
定义 f [ i ] [ j ] f[i][j] f[i][j] 为考虑前 i i i 个事件,选择不超过 j j j 的最大价值
对于每个事件,都有选择与不选两种选择:
-
不选: f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j] = f[i - 1][j] f[i][j]=f[i−1][j]
-
选:找到第 i i i 件事件之前,与第 i i i 件事件不冲突的事件,记为 last,则有 f [ i ] [ j ] = f [ l a s t ] [ j − 1 ] + v a l u e i f[i][j] = f[last][j - 1] + value_i f[i][j]=f[last][j−1]+valuei
两者取 m a x max max,则是 f [ i ] [ j ] f[i][j] f[i][j] 的值。
class Solution {
public int maxValue(int[][] es, int k) {
int n = es.length;
Arrays.sort(es, (a, b)->a[1]-b[1]);
// f[i][j] 代表考虑前 i 个事件,选择不超过 j 的最大价值
int[][] f = new int[n + 1][k + 1];
for (int i = 1; i <= n; i++) {
int[] ev = es[i - 1];
int s = ev[0], e = ev[1], v = ev[2];
// 找到第 i 件事件之前,与第 i 件事件不冲突的事件
// 对于当前事件而言,冲突与否,与 j 无关
int last = 0;
for (int p = i - 1; p >= 1; p--) {
int[] prev = es[p - 1];
if (prev[1] < s) {
last = p;
break;
}
}
for (int j = 1; j <= k; j++) {
f[i][j] = Math.max(f[i - 1][j], f[last][j - 1] + v);
}
}
return f[n][k];
}
}