問題描述
在一場電影節中,將播放 n 部電影,Syrjälä 的電影俱樂部有 k 位成員,他們都會參加這場電影節。
你已經知道每部電影的開始與結束時間
每位成員在同一時間只能完整觀看一部電影
請你計算:如果成員們安排得最優化,最多可以完整觀看幾部電影?
練習題
這題我們可以貪婪一點,對於將電影按照開始時間排,維護一個 k 個人看電影的 multiset 存結束時間,若:
後一部電影開始時間 >= 最早結束的電影,如此原本看那部最早結束電影的人就可以緊接著後一部,並將 ans + 1
後一部電影開始時間 < 最晚結束的電影,這樣代表讓成員看這部電影比較好,因為越早結束越有可能看更多部,因此可以把目前最晚結束的電影刪除,改成讓那個人看後一部電影,ans 不用加 1 是因為在第一點的時候已經加過了,我們只是替換那個人看的電影,「替換最晚結束的那部」,可以釋放出最多的時間,使未來安排可能性最大化
- 記得最後要輸出 ans + s.size(),ans 代表看完的電影,s.size() 代表 set 裡還在看電影的成員
完整程式碼
#include <bits/stdc++.h>
using namespace std;
#define ll long long
bool cmp(vector<int> a, vector<int> b) {
return a[0] < b[0];
}
int main() {
int n, k;
cin >> n >> k;
vector<vector<int>> vec;
for (int i = 0; i < n; i++) {
int start, end;
cin >> start >> end;
vec.push_back({start, end});
}
sort(vec.begin(), vec.end(), cmp);
int ans = 0;
multiset<int> s;
for (int i = 0; i < k; i++) {
s.insert(vec[i][1]);
}
for (int i = k; i < n; i++) {
int mn = *s.begin();
int mx = *s.rbegin();
if (vec[i][0] >= mn) {
ans++;
s.erase(s.begin());
s.insert(vec[i][1]);
} else if (vec[i][1] < mx) {
s.erase(prev(s.end()));
s.insert(vec[i][1]);
}
}
cout << ans + s.size();
}