这道题我们举个例子,假如有四个区间段,在这四个区间段上都要有点覆盖,最小的点数是2:
因此我们发现我们选点的时候尽可能往区间段的右端点选,这样就有可能覆盖两个区间。
因此我们可以给出如下思路:
当前区间已经包含点的情况就是图(a-1)的情况,
当前区间不包含点的情况如下:
该情况总结:假如有cnt的区间就要有cnt个点
code
时间复杂度:O(nlongn)
//以右端点排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define pll pair<int ,int>
vector<pair<int , int>>a;
int n ,nums = 1;
bool cmp(pll x , pll y){
return x.second < y.second;
}
int main()
{
cin >> n;
while( n--)
{
pll x;
cin>>x.first>>x.second;
a.push_back(x);
}
sort (a.begin() , a.end() , cmp);
for (int i = 1 , j = 0; i < a.size() ; ++i)
{
if (a[i].first > a[j].second ) {//如果当前区间左端点大于上一个区间右端点
nums++;//说明不重合,点数+1
j = i;//更新上一次的索引
}
// else {
// if (a[i].second < a[j].second) j = i; //求min(即该交集的最右边属于那个原集合)
// }
}
cout<<nums;
return 0;
}
这道题的代码和上面的一样。