题目:
数轴上有 n 个闭区间 [a_i, b_i]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)
Input:
第一行1个整数N(N<=100)
第2~N+1行,每行两个整数a,b(a,b<=100)
Output:
一个整数,代表选点的数目
Examples:
Input
2
1 5
4 6
Output
1
Input
3
1 3
2 5
4 6
Output
2
思路:
该题的贪心策略是:选取区间的最后一个点。将所有区间按end从小到大排序,end相同时,按照be从大到小排序。
证明:
1、当区间包含时,小区间中若存在一点,则大区间中也一定存在一点,所以我们应当优先选取小区间中的点,从而使大区间不需要取点。如果出现区间包含情况,按照此种排序方法遍历时会优先选取小区间,则此种情况下贪心策略是正确的。
2、当区间的开始点按递增顺序排列时,选择区间内最后的一点显然可以包括更多的区间,则此种情况下贪心策略也是正确的。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
struct zone
{
int be;
int end;
};
bool cmp(zone a, zone b)
{
if (a.end == b.end)
return a.be > b.be;
return a.end < b.end;
}
int main()
{
int be, end, n, count;
while (scanf("%d",&n)!=EOF)
{
count = 1;
zone *temp = new zone[n];
for (int i = 0; i < n; i++)
{
cin >> be >> end;
temp[i].be = be;
temp[i].end = end;
}
sort(temp,temp+n,cmp);
int j = 0;
for (int i = 1; i < n; i++)
{
if (temp[i].be > temp[j].end)
{
j = i;
count++;
}
}
cout << count << endl;
}
return 0;
}