Мы можем достичь решения O (nlogn) с помощью подхода динамического программирования. В частности, мы хотим рассмотреть размер наименьшего набора, включая задание k th и сопоставление первых k
заданий (упорядоченных по времени начала), которые мы обозначим S(k)
. Сначала мы должны добавить вспомогательное задание (∞, ∞), поэтому результатом будет наше решение DP для этого окончательного задания минус один.
Чтобы вычислить S(k)
, рассмотрим задание p(k)
, которое заканчивается до задания k
, но имеет максимальное время начала. Обратите внимание, что p
является возрастающей функцией. S(k)
будет тогда на единицу больше минимального S(i)
с end(i) > start(p(k))
.
Мы можем эффективно найти эту работу, поддерживая (S(k)
упорядоченный минимум) кучу потенциальных работ. После вычисления каждого S(k)
мы добавляем задание в кучу. Когда мы хотим получить работу, мы удаляем рабочие места в куче, которые заканчиваются слишком рано, пока не найдем подходящую. В общей сложности это займет не более O (nlogn), поскольку мы выполняем не более O (n) каждой операции кучи (pop / peek / push).
Остальная часть задачи заключается в эффективном вычислении значений p(k)
. Один из способов сделать это - перебирать все начало и конец задания (с увеличением времени), отслеживая последнее начальное задание.