B-区间选点
Description
数轴上有 n 个闭区间 [a_i, b_i]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。要求输入n以及n个区间,输出选点的数目
Sample
Input
2
1 5
4 6
Output
1
Input
3
1 3
2 5
4 6
Output
2
Idea
首先将所有区间按右边界升序,右边界相同时左边界降序进行排列。对每个区间设置一个标志flag判断该区间是否已经有一个点,依序对每个区间进行判断,如果其中还没有点,取该区间的右边界确定为一点,可以使得该点被包含的区间个数最大化,体现贪心算法,然后对该区间之后的每个区间,判断这个点是否也在这些区间中,是则改变其标志,在之后的循环中直接跳过它。
Summary
该题属于区间问题之一,基本思想是贪心,遵守的贪心准则是对于其中还没有点的区间取其右边界为一点,使效益最大化,在正确的排序之后,这个点要么在后面区间当中要么小于其他区间的左边界,可以保证没有区间被忽略。
Codes
#include <iostream>
#include <algorithm>
using namespace std;
int n;
struct time {
int a;
int b;
bool flag = false;
}t[100];
bool compare(time x, time y) {
if (x.b != y.b)return x.b < y.b;
else return x.a > y.a;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> t[i].a >> t[i].b;
sort(t, t + n, compare);
int count = 0;
int i = 0;
while (i<n) {
if (t[i].flag) {
i++; continue;
}
int b;
if (i < n) { b = t[i].b; count++; t[i].flag = true; i++; }
int index = i;
while (index < n) {
if (t[index].b >= b && t[index].a <= b) {
t[index].flag = true;
index++;
}
else index++;
}
}
printf("%d\n", count);
}