//本题其实很简单,就是一个贪心,但是看到dis里面好多人说查分约束以及spfa,回去用这个实现以下,还没有用过。
这个贪心是怎么想到的呢,每个区间至少要两个,那么很容易想到排序后后两个肯定是最优的,必选。如果后面的区间不覆盖,那么就+2,如果有覆盖,那么就要保持下一个区间的后两个和前一个的并集。然后+1.主要是第二种情况,一定要注意。
代码:
//很好的一个贪心算法
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
struct node
{
int a;
int b;
bool operator < (const node & other)const
{
if(a<other.a)
return true;
else if(a==other.a)
{
if(b<other.b)
return true;
else
return false;
}
else
return false;
}
}num[10010];
int main()
{
int i,j,n,a,b,cnt=2;
scanf("%d",&n);
for(i=0;i<n;++i)
{
scanf("%d%d",&num[i].a,&num[i].b);
}
sort(num,num+n);
//a=num[0].a;
b=num[0].b;//贪心排完序后肯定是后两个,也就是后两个是最优的。
a=b-1;
//j=0;
for(i=1;i<n;++i)
{
if(b<num[i].a)//如果没有重叠,那么直接加2下一个。
{
cnt+=2;
b=num[i].b;
a=b-1;
continue;
}
if(a<num[i].a)//如果前一个的左边界靠左那么左边界要换,换成……
{
a=(b>num[i].b-1)?num[i].b-1:b;
b=num[i].b;//右边界不变。
cnt++;
continue;
}
if(b>num[i].b)//如果右边界较大,直接更换右边界,求交集。
{
b=num[i].b;
}
}
printf("%d/n",cnt);
return 0;
}