[贪心]Exercise Week3 B-区间选点

题意

数轴上有 n 个闭区间 [a_i, b_i]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)

样例

样例输入:
第一行1个整数N(N<=100)
第2~N+1行,每行两个整数a,b(a,b<=100)
3
1 3
2 5
4 6
样例输出:
一个整数,代表选点的数目
2


思路

经过学长的暗示(明示),可以得知本题是用贪心来做的,所以我们要先确定一个贪心的策略。

由于本题的参数也很简单,每个区间只有a,b两个变量,所以我们可以从a b b-a中来选择

选尽量少的点的话,我们肯定是希望每一个区间选的点都能被其他尽可能多的区间包含,以a为标准贪心显然是不好的,举个最简单的例子,有两个区间 [1,5] 和 [2,4],很显然只需要一个点就可以满足要就 但以a为标准的话,我们会先处理[1,5] 但无论选择 1 还是 5,都无法使[2,4]满足条件,故不合适

这么看来只有b靠谱了。如果以b为标准升序排列所有区间,如果想让点被尽可能多的区间包含,我们肯定是要选择当前区间的右端点(越往右越好,因为我们是按右端点升序排列的)但如果右区间相同了呢?学长给的方案是按左端点降序排列,但是我感觉好像不需要(自己冷静分析+可能数据太水),只需要按右端点排列就好


总结

本题过程:
1.先根据右端点对区间排序
2.在第一个区间的右端点上放上一个点
3.对第2~n个区间,判断最新放上的点在不在该区间内,若在 则转到下个区间,否则在该区间的右端点上放一个点 同时记录放下的点

对贪心的思考:
如果没有学长的暗示,可能想起来还需要个几天…因为不知道自己认为的贪心思路是否是正确的,看来需要多接触点贪心的思想(orz)


代码

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
int n;
struct node
{
	int a,b;
	bool operator < (const node & x) const{
		if(b!=x.b)	return b<x.b;
		else return a>x.a;..
	}
} s[1010];
int p[1010];
int tnt;
int main()
{
	cin>>n;

	for(int i=1;i<=n;i++)	cin>>s[i].a>>s[i].b;
	sort(s+1,s+n+1);
	p[++tnt]=s[1].b;
	for(int i=2;i<=n;i++)
		if(s[i].a<=p[tnt]&&s[i].b>=p[tnt])	continue;
		else	p[++tnt]=s[i].b;
	
	cout<<tnt<<endl;
	system("pause");
	return 0;
} 

发布了12 篇原创文章 · 获赞 0 · 访问量 517

猜你喜欢

转载自blog.csdn.net/linshen_jianhai/article/details/104698750