问题描述
数轴上有 n 个闭区间 [a_i, b_i]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。
Input
第一行1个整数N(N<=100)
第2~N+1行,每行两个整数a,b(a,b<=100)
Output
一个整数,代表选点的数目
Example
Input
2
1 5
4 6
Output
1
思路
贪心思想,解法是每一个点尽可能覆盖更多的区间。对所有左边界和右边界带编号排序,对于没有覆盖过的右边界最小的区间,必然是有一个点要覆盖它的,否则若是这个点不在区间之内,之后就没有可能覆盖的点了。那么这一个点还能覆盖哪些区间?只要左边界小于等于这个区间的右边界就可以被覆盖。按照这个策略执行直到覆盖所有的区间。
总结
贪心可以说是一种简单粗暴的求最优解的方法,直接去考虑理想情况下最优的策略而不用担心有其他限制,而且可以用反证来证明策略的正确性,同时效率极高。
代码
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define mem(a,s) memset(a,s,sizeof(a))
struct L{
int l,x;
}lx[200];
struct R{
int r,x;
}rx[200];
bool b[200];
bool cmp(L&x,L&y){
return x.l<y.l;
}
bool CMP(R&x,R&y){
return x.r<y.r;
}
int main(){
// freopen("1.txt","r",stdin);
int n;
cin>>n;
mem(b,false);
rep(i,1,n){
cin>>lx[i].l>>rx[i].r;
lx[i].x=rx[i].x=i;
}
sort(lx+1,lx+n+1,cmp);
sort(rx+1,rx+n+1,CMP);
int i=1,j=1,sum=0;
while(1){
sum++;
while(lx[i].l<=rx[j].r&&i<=n){
b[lx[i].x]=true;
i++;
}
while(b[rx[j].x]&&j<=n)
j++;
if(i>n&&j>n)break;
}
cout<<sum;
return 0;
}