Skip to content

Commit c48f4bf

Browse files
committed
feat: add solutions to lc problem: No.1751
No.1751.Maximum Number of Events That Can Be Attended II
1 parent d7be5f9 commit c48f4bf

File tree

7 files changed

+508
-0
lines changed

7 files changed

+508
-0
lines changed

solution/1200-1299/1235.Maximum Profit in Job Scheduling/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ $$
9696

9797
时间复杂度 $O(n \times \log n)$,其中 $n$ 是工作的数量。
9898

99+
相似题目:[1751. 最多可以参加的会议数目 II](/solution/1700-1799/1751.Maximum%20Number%20of%20Events%20That%20Can%20Be%20Attended%20II/README.md)
100+
99101
<!-- tabs:start -->
100102

101103
### **Python3**

solution/1700-1799/1751.Maximum Number of Events That Can Be Attended II/README.md

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,255 @@
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60+
**方法一:记忆化搜索 + 二分查找**
61+
62+
我们先将会议按照开始时间从小到大排序,然后设计一个函数 $dfs(i, k)$ 表示从第 $i$ 个会议开始,最多参加 $k$ 个会议的最大价值和。答案即为 $dfs(0, k)$。
63+
64+
函数 $dfs(i, k)$ 的计算过程如下:
65+
66+
对于第 $i$ 个会议,我们可以选择参加或者不参加。如果不参加,那么最大价值和就是 $dfs(i + 1, k)$,如果参加,我们可以通过二分查找,找到第一个开始时间大于第 $i$ 个会议结束时间的会议,记为 $j$,那么最大价值和就是 $dfs(j, k - 1) + value[i]$。取二者的较大值即可。即:
67+
68+
$$
69+
dfs(i, k) = \max(dfs(i + 1, k), dfs(j, k - 1) + value[i])
70+
$$
71+
72+
其中 $j$ 为第一个开始时间大于第 $i$ 个会议结束时间的会议,可以通过二分查找得到。
73+
74+
由于函数 $dfs(i, k)$ 的计算过程中,会调用 $dfs(i + 1, k)$ 和 $dfs(j, k - 1)$,因此我们可以使用记忆化搜索,将计算过的值保存下来,避免重复计算。
75+
76+
时间复杂度 $O(n\times \log n + n\times k)$,其中 $n$ 为会议数量。
77+
78+
**方法二:动态规划 + 二分查找**
79+
80+
我们可以将方法一中的记忆化搜索改为动态规划。
81+
82+
先将会议排序,这次我们按照结束时间从小到大排序。然后定义 $dp[i][j]$ 表示前 $i$ 个会议中,最多参加 $j$ 个会议的最大价值和。答案即为 $dp[n][k]$。
83+
84+
对于第 $i$ 个会议,我们可以选择参加或者不参加。如果不参加,那么最大价值和就是 $dp[i][j]$,如果参加,我们可以通过二分查找,找到最后一个结束时间小于第 $i$ 个会议开始时间的会议,记为 $h$,那么最大价值和就是 $dp[h+1][j - 1] + value[i]$。取二者的较大值即可。即:
85+
86+
$$
87+
dp[i+1][j] = \max(dp[i][j], dp[h+1][j - 1] + value[i])
88+
$$
89+
90+
其中 $h$ 为最后一个结束时间小于第 $i$ 个会议开始时间的会议,可以通过二分查找得到。
91+
92+
时间复杂度 $O(n\times \log n + n\times k)$,其中 $n$ 为会议数量。
93+
94+
相似题目:[1235. 规划兼职工作](/solution/1200-1299/1235.Maximum%20Profit%20in%20Job%20Scheduling/README.md)
95+
6096
<!-- tabs:start -->
6197

6298
### **Python3**
6399

64100
<!-- 这里可写当前语言的特殊实现逻辑 -->
65101

66102
```python
103+
class Solution:
104+
def maxValue(self, events: List[List[int]], k: int) -> int:
105+
@cache
106+
def dfs(i, k):
107+
if i >= len(events):
108+
return 0
109+
_, e, v = events[i]
110+
ans = dfs(i + 1, k)
111+
if k:
112+
j = bisect_right(events, e, lo=i+1, key=lambda x: x[0])
113+
ans = max(ans, dfs(j, k - 1) + v)
114+
return ans
115+
116+
events.sort()
117+
return dfs(0, k)
118+
```
67119

120+
```python
121+
class Solution:
122+
def maxValue(self, events: List[List[int]], k: int) -> int:
123+
events.sort(key=lambda x: x[1])
124+
n = len(events)
125+
dp = [[0] * (k + 1) for _ in range(n + 1)]
126+
for i, (s, _, v) in enumerate(events):
127+
h = bisect_left(events, s, hi=i, key=lambda x: x[1])
128+
for j in range(1, k + 1):
129+
dp[i + 1][j] = max(dp[i][j], dp[h][j - 1] + v)
130+
return dp[n][k]
68131
```
69132

70133
### **Java**
71134

72135
<!-- 这里可写当前语言的特殊实现逻辑 -->
73136

74137
```java
138+
class Solution {
139+
private int[][] events;
140+
private int[][] f;
141+
private int n;
142+
143+
public int maxValue(int[][] events, int k) {
144+
Arrays.sort(events, (a, b) -> a[0] - b[0]);
145+
this.events = events;
146+
n = events.length;
147+
f = new int[n][k + 1];
148+
return dfs(0, k);
149+
}
150+
151+
private int dfs(int i, int k) {
152+
if (i >= n || k <= 0) {
153+
return 0;
154+
}
155+
if (f[i][k] != 0) {
156+
return f[i][k];
157+
}
158+
int j = search(events, events[i][1], i + 1);
159+
int ans = Math.max(dfs(i + 1, k), dfs(j, k - 1) + events[i][2]);
160+
f[i][k] = ans;
161+
return ans;
162+
}
163+
164+
private int search(int[][] events, int x, int i) {
165+
int left = i, right = n;
166+
while (left < right) {
167+
int mid = (left + right) >> 1;
168+
if (events[mid][0] > x) {
169+
right = mid;
170+
} else {
171+
left = mid + 1;
172+
}
173+
}
174+
return left;
175+
}
176+
}
177+
```
178+
179+
```java
180+
class Solution {
181+
public int maxValue(int[][] events, int k) {
182+
Arrays.sort(events, (a, b) -> a[1] - b[1]);
183+
int n = events.length;
184+
int[][] dp = new int[n + 1][k + 1];
185+
for (int i = 0; i < n; ++i) {
186+
int s = events[i][0], v = events[i][2];
187+
int h = search(events, s, i);
188+
for (int j = 1; j <= k; ++j) {
189+
dp[i + 1][j] = Math.max(dp[i][j], dp[h][j - 1] + v);
190+
}
191+
}
192+
return dp[n][k];
193+
}
194+
195+
private int search(int[][] events, int x, int n) {
196+
int left = 0, right = n;
197+
while (left < right) {
198+
int mid = (left + right) >> 1;
199+
if (events[mid][1] >= x) {
200+
right = mid;
201+
} else {
202+
left = mid + 1;
203+
}
204+
}
205+
return left;
206+
}
207+
}
208+
```
209+
210+
### **C++**
211+
212+
```cpp
213+
class Solution {
214+
public:
215+
int maxValue(vector<vector<int>>& events, int k) {
216+
sort(events.begin(), events.end());
217+
int n = events.size();
218+
vector<vector<int>> f(n, vector<int>(k + 1));
219+
function<int(int, int)> dfs = [&](int i, int k) -> int {
220+
if (i >= n || k <= 0) return 0;
221+
if (f[i][k]) return f[i][k];
222+
vector<int> t = {events[i][1]};
223+
int j = upper_bound(events.begin() + i + 1, events.end(), t, [&](auto& l, auto& r) -> bool { return l[0] < r[0]; }) - events.begin();
224+
int ans = max(dfs(i + 1, k), dfs(j, k - 1) + events[i][2]);
225+
f[i][k] = ans;
226+
return ans;
227+
};
228+
return dfs(0, k);
229+
}
230+
};
231+
```
232+
233+
```cpp
234+
class Solution {
235+
public:
236+
int maxValue(vector<vector<int>>& events, int k) {
237+
sort(events.begin(), events.end(), [&](auto& l, auto& r) -> bool { return l[1] < r[1]; });
238+
int n = events.size();
239+
vector<vector<int>> dp(n + 1, vector<int>(k + 1));
240+
for (int i = 0; i < n; ++i) {
241+
int s = events[i][0], v = events[i][2];
242+
int h = lower_bound(events.begin(), events.begin() + i, s, [](auto& e, int x) { return e[1] < x; }) - events.begin();
243+
for (int j = 1; j <= k; ++j) {
244+
dp[i + 1][j] = max(dp[i][j], dp[h][j - 1] + v);
245+
}
246+
}
247+
return dp[n][k];
248+
}
249+
};
250+
```
251+
252+
### **Go**
253+
254+
```go
255+
func maxValue(events [][]int, k int) int {
256+
sort.Slice(events, func(i, j int) bool { return events[i][0] < events[j][0] })
257+
n := len(events)
258+
f := make([][]int, n)
259+
for i := range f {
260+
f[i] = make([]int, k+1)
261+
}
262+
var dfs func(i, k int) int
263+
dfs = func(i, k int) int {
264+
if i >= n || k <= 0 {
265+
return 0
266+
}
267+
if f[i][k] > 0 {
268+
return f[i][k]
269+
}
270+
j := sort.Search(n, func(h int) bool { return events[h][0] > events[i][1] })
271+
ans := max(dfs(i+1, k), dfs(j, k-1)+events[i][2])
272+
f[i][k] = ans
273+
return ans
274+
}
275+
return dfs(0, k)
276+
}
277+
278+
func max(a, b int) int {
279+
if a > b {
280+
return a
281+
}
282+
return b
283+
}
284+
```
75285

286+
```go
287+
func maxValue(events [][]int, k int) int {
288+
sort.Slice(events, func(i, j int) bool { return events[i][1] < events[j][1] })
289+
n := len(events)
290+
dp := make([][]int, n+1)
291+
for i := range dp {
292+
dp[i] = make([]int, k+1)
293+
}
294+
for i, event := range events {
295+
h := sort.Search(i, func(k int) bool { return events[k][1] >= event[0] })
296+
for j := 1; j <= k; j++ {
297+
dp[i+1][j] = max(dp[i][j], dp[h][j-1]+event[2])
298+
}
299+
}
300+
return dp[n][k]
301+
}
302+
303+
func max(a, b int) int {
304+
if a > b {
305+
return a
306+
}
307+
return b
308+
}
76309
```
77310

78311
### **...**

0 commit comments

Comments
 (0)