凌乱的yyy / 线段覆盖

题目背景

快 noip 了,yyy 很紧张!

题目描述

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

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

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

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

输入格式

第一行是一个整数 \(n\) ,接下来 \(n\) 行每行是 \(2\) 个整数 \(a_{i},b_{i}\) ( \(a_{i}<b_{i}\) ),表示比赛开始、结束的时间。

输出格式

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

样例 #1

样例输入 #1

3
0 2
2 4
1 3

样例输出 #1

2

提示

对于 \(20\%\) 的数据, \(n \le 10\)

对于 \(50\%\) 的数据, \(n \le 10^3\)

对于 \(70\%\) 的数据, \(n \le 10^{5}\)

对于 \(100\%\) 的数据, \(1\le n \le 10^{6}\)\(0 \le a_{i} < b_{i} \le 10^6\)

解析

贪心

贪心的策略是先给所有的区间按照右边界排序

其中一定要选择第一个区间

为什么?

现在$ (b_1)<=(b_2)$

那么考虑两种\((a_1)\)\((a_2)\)的关系

  1. \((a_1)>(a_2)\)
    那么两个区间如下图
    image

那么选择上面的区间一定是划算的

  1. 因为没有已经排除第一种情况,所以所有区间的关系如下:

\[(a_1) \leq(a_2) \leq(a_3) \leq(a_4)... \leq(a_n) \]

图:
image

如果区间2和区间1不相交,那没有影响

如果相交了,仍然是选第一个

因为如果不选第二个,红色部分的长度是没有影响的

因为它不与任何一个区间相交,区间1的有效部分只剩下灰色部分

而灰色部分又被区间2所包含,成为了第一种情况

所以无论如何,选择第一个总是有利的

选择第一个后,还要标记所以与它相交的区间(不能选了)

代码

#include<bits/stdc++.h>
using namespace std;
struct px{
	int a;
	int b;
}x[2000000];
bool cmp(px x,px y){
	return x.b<y.b;
}

int main(){
	int n,sum=1,mi;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		cin >> x[i].a >> x[i].b;
	}
		
	sort(x+1,x+n+1,cmp);
	mi=x[1].b;
	int j=1;
	while(j<=n)
	{
		j++;
		if(x[j].a>=mi)
		{
			sum++;
			mi=x[j].b;
		}
	}
	cout << sum;
	return 0;
}
posted @ 2023-06-17 09:19  Momo·Trace  阅读(18)  评论(0编辑  收藏  举报