原题链接:
题解:
方法一:端点贪心排序
方法二:区间拆分离散化
大家可以把这个问题想象成活动安排问题
有若干个活动,每个活动有其开始时间和结束时间,同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个教室?
有时间冲突的活动不能安排在同一间教室,与该问题的限制条件相同,即最小需要的教室个数即为该题答案。
我们可以把所有开始时间和结束时间排序,遇到开始时间就把需要的教室加1,遇到结束时间就把需要的教室减1,在一系列需要的教室个数变化的过程中,峰值就是多同时进行的活动数,也是我们至少需要的教室数。
相当于是把原来的活动区间拆分,按照时间进行排序(离散化)后进行处理。
需要注意的是当出现[1,3]、[3,4]这种情况时,3==3,我们一定要让[3,4]中的3排序后比[1,3]靠前,因为这种情况最少需要2个教室。
代码:
方法一:
#include<bits/stdc++.h>
using namespace std;
using PII = pair<int, int>;
const int N = 1e5 + 10, INF = 0x3f3f3f3f;
int n, res;
vector<PII> v;
int main() {
cin >> n;
for (int i = 0;i < n;i++) {
int a, b;cin >> a >> b;
v.push_back({ a,b });
}
sort(v.begin(), v.end());
priority_queue<int, vector<int>, greater<int>> que;
for (int i = 0;i < n;i++) {
if (que.empty() || que.top() >= v[i].first) que.push(v[i].second);//开新组
else {
que.pop();//可以放在一个组内,但是需要更新组内的右端点
que.push(v[i].second);
}
}
cout << que.size();
}
方法二:
#include<bits/stdc++.h>
using namespace std;
using PIB = pair<int, bool>;
const int N = 1e5 + 10, INF = 0x3f3f3f3f;
int n, res;
vector<PIB> v;
int main() {
cin >> n;
for (int i = 0;i < n;i++) {
int a, b;cin >> a >> b;
v.push_back({ a, 0 });//开始时间
v.push_back({ b, 1 });//结束时间
}
sort(v.begin(), v.end());
int tmp = 0;
for (auto i : v) {
if (i.second == 0) tmp++;
else tmp--;
res = max(res, tmp);
}
cout << res;
}