贪心-区间覆盖(题解)

题意:数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
不可能办到输出-1
思路:首先进行预处理,将不在区间[1, t]内的区间砍掉,然后按照左端点从小到大进行排序,当左端点相同时右端点从大到小排序,从起点开始选择区间,然后继续处理循环选择
总结:贪心问题关键找到多个指标,确定按哪个指标处理更优。
反思:刚开始TE,后来进行了优化,因为其实的区间是sort排好序的,所以可以在cover函数里面加入判断,预处理时不需要对所有预处理,而且每次都是选择起始点的区间,所以当区间起始点大于sx时说明以后的区间也不可取,所以break
代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int flag = 0;
struct interval
{
	int x, y;
	bool operator<(const interval& a)
	{
		if (x != a.x)  return x < a.x;
		return y > a.y;
	}
}ter[25002];

void cover(interval* ter, int k, int sx, int ty)
{
	int num = -1; bool ok = 0; int snum;
	for (int i = 0; i < k; i++)
	{
		if (ter[i].y<sx || ter[i].x>ty) continue;
		if (ter[i].x < sx)  ter[i].x = sx;
		if (ter[i].y > ty) ter[i].y = ty;
		if (ter[i].x == sx&&((ter[i].y-ter[i].x)>num))//判断区间//起始点与长度
		{
			num = ter[i].y - ter[i].x; ok = 1; snum = ter[i].y + 1;
			
		}
		if (ter[i].x >sx) break;
	}if (ok)
	{
		sx = snum;
		flag++; 
	}
	else
	{
		if (sx > ty)
			cout << flag;
		else cout << "-1"; return;

	}if (sx > ty)
	{
		cout << flag; return;
	}
	cover(ter, k, sx, ty);
}
int main()
{

	int n, t; scanf("%d%d", &n, &t); int k = 0;
	for (int i = 0; i < n; i++)
	{
		int x, y; 
		scanf("%d%d", &x, &y);
		if (y<1 || x>t) continue;
		if (x < 1) x = 1;
		if (y > t) y = t;
		ter[i].x = x; ter[i].y = y; k++;
	}
    sort(ter, ter + k);
	cover(ter, k, 1, t);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值