算法思路
用右端点排序,然后每当发现下面的某个区间左端点在当前考察区间右端点右边,就更新
可理解为:按右端点从小到大排序是因为这样可以只考虑当前考虑的区间的右端点,因为后面的区间的的右端点一定在此区间的右边,不会无缘无故被迫更新。
基于这种思路,考虑下面这两个题的联系
1.上题的正确性约束是此题的最值(要求最大)约束
上题要求每个区间都要被选到,所以每当下面没了的时候必须加点;
此题要求最大值,下面都没了还不立刻选下面的区间,那就不能保证最大了
2.此题的正确性约束是上题的最值(要求最小)约束
上题要求尽可能少地选点,故只要和现在考察的区间有交集,就不加新的点
此题要求区间不相交,故只要能和现在考察的区间有交集,都不能选
综合就是,当且仅当发现下面的某个区间左端点在当前考察区间右端点右面,一定更新,保证正确性和最值
#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()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d%d", &range[i].l, &range[i].r);
sort(range, range + n);
int res = 0, ed = -2e9;
for (int i = 0; i < n; i ++ )
if (ed < range[i].l)
{
res ++ ;
ed = range[i].r;
}
printf("%d\n", res);
return 0;
}