题意
数轴上有 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;
}