贪心思想——区间覆盖

分析:

区间覆盖问题描述:在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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值