思路:贪心
分析:
1 很明显的区间的最少覆盖问题,我们只要把这些区间按照“a从小到大,a相同按照b从大到小”,然后我们逐个枚举求出最少的区间
2 我们需要维护一个变量pre表示现在已经覆盖的右端点,现在我们只需要去找到那些左端点小于pre的最大的右端点Max和左端点为pre+1的右端点tmp,求max(Max , tmp)即可。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 5010;
struct seg{
int left;
int right;
bool operator<(const seg& s1)const{
if(left < s1.left)
return true;
else if(left == s1.left && right > s1.right)
return true;
return false;
}
};
seg s[MAXN];
int main(){
int Case , n;
scanf("%d" , &Case);
while(Case--){
scanf("%d" , &n);
for(int i = 0 ; i < n ; i++)
scanf("%d%d" , &s[i].left , &s[i].right);
sort(s , s+n);
int ans = 1;
int pre = s[0].right;//初始化的右端点
while(1){
if(pre >= n) break;
int i , tmp = 0 , Max = 0;
ans++;
for(i = 0 ; s[i].left <= pre ; i++)
Max = max(Max , s[i].right);
if(s[i].left == pre+1) //找左端点是pre+1的右端点的值
tmp = s[i].right;
pre = max(tmp , Max); //求最大值
}
printf("%d\n" , ans);
}
return 0;
}