P1803 凌乱的yyy / 线段覆盖

P1803 凌乱的yyy / 线段覆盖

题目

现在各大 oj 上有 n 个比赛,每个比赛的开始、结束的时间点是知道的。

yyy 认为,参加越多的比赛,noip 就能考的越好(假的)。

所以,他想知道他最多能参加几个比赛。

由于 yyy 是蒟蒻,如果要参加一个比赛必须善始善终,而且不能同时参加 2 个及以上的比赛。

输入

第一行是一个整数 n,接下来 n 行每行是 2 个整数 ai,bi (ai<bi),表示比赛开始、结束的时间。

输出

一个整数最多参加的比赛数目。

样例

输入

3
0 2
2 4
1 3

输出

2

提示

  • 对于 20% 的数据,n10
  • 对于 50% 的数据,n103
  • 对于 70% 的数据,n105
  • 对于 100% 的数据,1n1060ai<bi106

思路

该问题属于“选择不相交的区间问题”。通过分析可以得到,区间越早终止,越对后面的区间“有利”,因此,按右端点大小排序。

容易分析出,最早结束的区间一定要选择,图中 1 区间一定要选。选择完 1 区间后,很快发现其余区间构成新的问题,且与 1 区间相交的线段不能选择。如此一来,贪心策略便得出:选择最多个不相交的区间问题,首先对右端点进行排序,然后依次选择左端点大于前一个已经选择的区间右端点的区间。上图例子中,应该选择 1,2,5 区间。


代码

#include <bits/stdc++.h>

using namespace std;

int n, pre, cnt, ed;

struct node
{
	int s, e;
} p[1000010];

bool cmp(const node &u, const node &v)
{
	if (u.e < v.e)
		return 1;
	else if (u.e == v.e)
	{
		if (u.s < v.s)
			return 1;
		else
			return 0;
	}
	return 0;
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i ++ )
		scanf("%d %d", &p[i].s, &p[i].e);
	sort(p + 1, p + n + 1, cmp);
	ed = p[1].e;
	for (int i = 2; i <= n; i ++ )
	{
		if (p[i].s >= ed)
		{
			ed = p[i].e;
			cnt ++;
		}
	}
	cout << cnt + 1 << '\n';
	return 0;
}
posted @   IronMan_PZX  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
Title
点击右上角即可分享
微信分享提示