Відсортуємо відрізки за їхніми правими кінцями. Виберемо перший відрізок і видалимо всі відрізки, що перетинаються з ним. Потім виберемо наступний найбільш лівий відрізок і знову видалимо відрізки, що перетинаються з ним. Використовуючи такий жадібний алгоритм, ми виберемо максимальну кількість неперетинаючихся відрізків.
Реалізація алгоритму
Оголосимо клас segment, що буде зберігати інтервал [start; fin).
class segment
{
public:
int start, fin;
segment(int start, int fin) : start(start), fin(fin) {}
};Набір вхідних інтервалів зберігаємо у векторі .
vector<segment> v;Функція f є компаратором для сортування інтервалів за зростанням їхніх правих кінців.
int f(segment a, segment b)
{
return a.fin < b.fin;
}Основна частина програми. Читаємо вхідні дані.
scanf("%d", &n);
while (n--)
{
scanf("%d %d", &a, &b);
v.push_back(segment(a, b));
}Сортуємо відрізки.
sort(v.begin(), v.end(), f);Нехай поточний оброблюваний інтервал міститься в змінній . Почнемо алгоритм з нульового інтервалу, встановивши cur = 0. У змінній будемо підраховувати кількість вибраних інтервалів. Оскільки нульовий інтервал уже вибрано, встановимо res = 1.
cur = 0; res = 1;Перебираємо інтервали, починаючи з i = 1.
for (i = 1; i < v.size(); i++)
{Для кожного інтервалу шукаємо той, у якого початок не менший від кінця поточного . Як тільки такий інтервал знайдено, вибираємо його і присвоюємо номер цього нового інтервалу.
if (v[i].start >= v[cur].fin)
{
cur = i;
res++;
}
}Виводимо максимальну кількість неперетинаючихся інтервалів.
printf("%d\n", res);Реалізація на Java
import java.util.*;
class Segment
{
int start, fin;
public Segment(int start, int fin)
{
this.start = start;
this.fin = fin;
}
}
public class Main
{
public static class MyFun implements Comparator<Segment>
{
public int compare(Segment a, Segment b)
{
return a.fin - b.fin;
}
}
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
int n = con.nextInt();
ArrayList<Segment> seg = new ArrayList<Segment>();
for (int i = 0; i < n; i++)
{
int a = con.nextInt();
int b = con.nextInt();
seg.add(new Segment(a,b));
}
Collections.sort(seg, new MyFun());
int cur = 0, res = 1;
for (int i = 1; i < seg.size(); i++)
{
if (seg.get(i).start >= seg.get(cur).fin)
{
cur = i;
res++;
}
}
System.out.println(res);
con.close();
}
}