AcWing 905. 区间选点
题目描述
给定 N 个闭区间
[ai,bi]
,请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。输出选择的点的最小数量。
位于区间端点上的点也算作区间内。
输入格式
第一行包含整数 N,表示区间数。
接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示所需的点的最小数量。
数据范围
\(1≤N≤10^5\)
\(−10^9≤ai≤bi≤10^9\)输入样例:
3 -1 1 2 4 3 5
输出样例:
2
贪心算法求解
分析
把所有区间按照右端点排序
初始化当前区间ed = -1e9 - 7
,遍历所有区间u
- 如果区间
u的左端点 > ed
,说明本区间与区间u没有交集,res++
,并且更新ed = u的右端点
- 否则说明本区间与区间u没有交集,只要在ed取一个点,这个点一定既属于本区间,又属于区间u,直接pass区间u即可
具体证明:https://www.acwing.com/solution/content/16905/
代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int, int> Pair;
const int N = 100010;
vector<Pair> s;
bool cmp(Pair a, Pair b)
{
return a.second < b.second;
}
int main()
{
int n;
int res = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
Pair t;
scanf("%d%d", &t.first, &t.second);
s.push_back(t);
}
sort(s.begin(), s.end(), cmp); // 按照区间右端点从小到大排序
int ed = -1e9 - 7;
for(Pair t : s)
{
if(ed < t.first)
{
res ++;
ed = t.second;
}
}
cout << res << endl;
return 0;
}
时间复杂度
O(n)