题意:给定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;
}