905. 区间选点
文章目录
- 题目描述
- 输入格式:
- 输出格式:
- 数据范围
- 输入样例
- 输出样例
- 方法:贪心
- 解题思路
- 代码
- 复杂度分析:
题目描述
给定 N 个闭区间 [ a i , b i ] [a_i,b_i] [ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。
输出选择的点的最小数量。
位于区间端点上的点也算作区间内。
输入格式:
第一行包含整数 N,表示区间数。
接下来 N 行,每行包含两个整数 a i , b i a_i,b_i ai,bi,表示一个区间的两个端点。
输出格式:
输出一个整数,表示所需的点的最小数量。
数据范围
- 1 ≤ N ≤ 1 0 5 1≤N≤10^5 1≤N≤105
- − 1 0 9 ≤ a i ≤ b i ≤ 1 0 9 -10^9≤a_i≤b_i≤10^9 −109≤ai≤bi≤109
输入样例
3
-1 1
2 4
3 5
输出样例
2
方法:贪心
解题思路
贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。
- 将所有区间按右端点从小到大排序
- 维护点设置为负无穷,依次搜索每个区间
如果新区间的左端点 > 维护点,则将维护值更新成新区间的右端点;
如果新区间的右端点 <= 维护点,则说明维护点也在这个新区间内。
Tips
- 这里保存区间的左右端点采用了 struct 类型,按区间右端点进行排序需要对 struct 类型的数组自定义排序
//定义结构体
struct Type{
int a;
double b;
//升序需要的操作符函数
bool operator < (const Type& right) const
{
return a < right.a;
}//asscend
//降序需要的操作符函数
bool operator > (const Type& right) const
{
return a > right.a;
}//descend
};
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
struct Range {
int l, r;
bool operator < (const Range &W) const {
return r < W.r;
};
}range[N];
int main() {
cin >> n;
for(int i = 0; i < n; i++) {
int l, r;
cin >> l >> r;
range[i] = {l, r};
}
sort(range, range + n);
int res = 0, ed = -2e9;
for(int i = 0; i < n; i++)
if(range[i].l > ed) {
res++;
ed = range[i].r;
}
cout << res;
return 0;
}
复杂度分析:
- 时间复杂度: O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
- 空间复杂度: O ( n ) O(n) O(n)