题意:给定n个连续的区间,求一个集合。其中,n个区间的每一个区间都至少包含两个这个集合的元素。求这个集合元素的最小值。
题解:
1、先将所有区间按终点从小到大排序。
2、我们先取第一个区间(排好序的区间)的两个值,因为要使得结果最优,我们肯定选择最接近终点的那两个值。假设一个为Selem,一个为Eelem.此时,集合元素为ans = 2.
3、看下一个区间。如果这个区间的起点要小于等于Selem,那么我们可以肯定这个区间是不用计算的,因为它和之前的区间重合的部分大于两个元素,所以跳过之。
如果这个区间的起点要小于等于Eelem但是大于Selem,那么可以知道,之前的区间包括了Selem和Eelem,但是当前这个区间只包含了Eelem(只要包含了Selem和Eelem就是包含了两个集合的元素,因为Selem和Eelem属于集合),所以我们要为当前这个区间还要加一个元素,这个元素根据最优性考虑,当然是此时区间的最后一个元素最好。故我们调整一下Selem和Eelem两个值,使得其为最后两个加进集合的元素。集合元素ans++.
现在还有一种情况就是,如果当前区间的起点大于Eelem,那么可以知道,当前的区间没有包含一个集合的元素,那么我们就要在集合里加上两个元素,这两个元素当然是当前区间的最后两个最好,根据最优性原则。然后我们再更新Selem和Eelem的值即可。集合元素ans += 2.
4、输出ans即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 10010
struct line{
int s,t;
bool operator < (const line & q)const{
return t < q.t;
}
}p[MAXN];
int main(){
int n,m,ans, k, i, a, b;
int Selem,Eelem;
while(~scanf("%d",&n)){
for(int i = 0; i < n ; i++){
scanf("%d%d",&p[i].s,&p[i].t);
}
sort(p,p+n);
for(int i = 0; i < n ; i++){
printf("%d %d\n",p[i].s,p[i].t);
}
ans = 2;
Selem = p[0].t - 1;
Eelem = p[0].t;
for(int i = 1; i < n; i++){
if(p[i].s<= Selem){
continue;
}
else if(p[i].s <= Eelem){
Selem = Eelem;
Eelem = p[i].t;
ans ++;
continue;
}
else {
ans += 2;
Selem = p[i].t - 1;
Eelem = p[i].t;
continue;
}
}
printf("%d\n",ans);
}
return 0;
}