区间覆盖--贪婪算法

问题:

数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
不可能办到输出-1

input:

第一行:N和T
第二行至N+1行: 每一行一个闭区间。

output:

选择的区间的数目,不可能办到输出-1

sample input:

3 10
1 7
3 6
6 10

sample output:

2

题解:

这个题与区间选点问题大同小异,我们还是需要将区间进行排序,不过是先按左端点升序,再按照右端点升序,这样就可以保证我们区间是有序的。
之后我们从第一个区间开始,首先判断是否在一的右边,不在的话就开始循环,我们使用一个nowl,nowr记录现在选出的区间的范围。如果这个区间的左端点值小于nowl,右端点值小于的话没有意义,右端点值大于的话,就说明该区间覆盖了我们之间选择的区间,更新选择的区间的。如果这个区间的左端点大于我们选择的左端点,并且右端点大于我们选择的右端点,那么说明我们应该选择一个新的区间,并且如果左端点大于我们选择的右端点+1,说明不能覆盖。这样重复知道循环结束,或者已经覆盖要覆盖的区域。

完整代码:

#include <iostream>
#include <list>
#include <cstring>
#include <stdio.h>
#include <algorithm>
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct qu{
	int r;
	int l;
};
bool compare(qu &x,qu &y)     //新的比较函数
{
	if(x.l==y.l)
	{
		return x.r<y.r;
	}
	else
	{
		return x.l<y.l;
	}
}
int main(int argc, char** argv) {
	int n;
	int count=1;
	cin>>n;
	qu* jian=new qu[n];
	int t;
	cin>>t;
	bool is=true;
	for(int i=0;i<n;i++)
	{
		scanf("%d",&jian[i].l);
		scanf("%d",&jian[i].r);
	}
	sort(jian,jian+n,compare);
	int nowl=1;
	int nowr=1;
	if(jian[0].l>1)
	{
		is=false;
	}
	else
	{
		for(int i=0;i<n;i++)
		{
			if(jian[i].l<=nowl)
			{
				if(jian[i].r>nowr)	nowr=jian[i].r;
			}
			else
			{
				if(jian[i].r>nowr)
				{
					if(jian[i].l>nowr+1)
					{
						is=false;
						break;
					}
					count++;
					nowl=nowr+1;
					nowr=jian[i].r;
				}
			}
			if(nowr>=t)
			{
				break;
			}
		}
	}
	if(nowr>=t&&is)
	{
		cout<<count<<endl;
	}
	else
	{
		cout<<-1<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值