分析:
区间覆盖问题描述:在n个闭区间中,选择最少的区间,可以覆盖[1,t]线段。
做法:首先,把n个区间根据左端点a进行升序排序;
从amin=0开始,对于所有左端点ai<=amin+1的区间,选择bi(bmax)最大的区间(bmax最初初始化为amin)
然后amin=bmax,重复上面的做法。
如果bmax>=t,那么就可以覆盖了。
那么不可以覆盖的情况是什么样的?(没考虑清楚就是坑呀…)
1、区间中最小的ai>1;那么不能覆盖1这个点
2、在寻找最大的bi当中,没有符合的(即所有ai>amin+1);那么中间有断点
3、遍历完所有区间之后,发现最后的bmax<t,这样也不能覆盖
然后在处理的过程中,发现一些可以优化的点
1、预剪枝。在接收区间的时候,如果发现区间[ai ,bi]中ai>t,我们可以丢弃这个区间。
2、在对符合条件的区间(ai<=amin+1)找最大bi的时候,对bi<=amin的,也可以直接不要考虑了
具体问题:
数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
不可能办到输出-1
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int N;
struct space
{
int a;
int b;
bool operator < (const space &n) const{
return a<n.a;//按照a升序
}
}spa[35000];
int find(int min)
{
int max = min;
for(int i=0;i<N;i++)
{
if(spa[i].a>min+1)//不选这个区间
break;
else if(spa[i].b>min)
if(max<spa[i].b)
max=spa[i].b;
}
return max;
}
int main()
{
int flag=-1;
int T,min=0,max,count=0;
int x,y;
scanf("%d %d",&N,&T);//N个区间,覆盖到【1,T】
for(int i=0;i<N;i++)
{
scanf("%d %d",&x,&y);//输入区间
spa[i].a=x;spa[i].b=y;
//预剪枝
if(x>T){
i--;N--;}
}
//区间按照a排序
sort(spa,spa+N);
//首先取a<=1,而且b最大的spa[i],然后找a<b,而且b最大的spa[]
for(int i=0;i<N;i++)
{
//寻找a<=min,而且b最大的区间,记录下b用来更新min
max=find(min);count++;
if(max==min)//没有这样的区间
{
printf("%d\n",flag);flag=0;
break;
}
if(max>=T)//已经可以覆盖了
{
printf("%d\n",count);
break;
}
min=max;
}
if(max<T&&flag!=0) printf("%d\n",flag);
return 0;
}