Это взвешенное отклонение планирование интервалов ; это разрешимо в O(N log N)
с динамическим программированием .
Пусть интервал будет g(start, stop, score)
, и пусть они будут отсортированы по stop
. Для простоты давайте пока предположим, что все stop
уникальны.
Пусть best[i]
будет лучшим результатом, который мы можем получить, когда нам разрешено использовать g[1], ..., g[i]
. Конечно, нам не нужно использовать их все, и, как правило, мы не можем, потому что подмножество интервалов, которые мы используем, должно быть непересекающимся.
- Понятно
best[0] = 0
. То есть, поскольку мы не можем использовать какой-либо интервал, лучший результат, который мы можем получить, равен 0.
- Для любого
1 <= k <= N
имеем:
best[k] = max( best[k-1], best[j] + g[k].score )
, где
j
- это самый большой индекс, такой что g[j].stop < g[k].start
(j
может быть нулем)
То есть, учитывая, что нам разрешено использовать g[1], ... g[k]
, лучшее, что мы можем сделать, - это лучший результат этих двух вариантов:
- Мы не включаем
g[k]
. Таким образом, оценка этой опции составляет best[k-1]
.
- ... потому что это лучшее, что мы можем сделать с
g[1], ... g[k-1]
- Мы включаем
g[k]
, и слева от нас мы делаем все возможное, чтобы все гены не перекрывались с g[k]
, то есть со всеми g[1], ..., g[j]
, где g[j].stop < g[k].start
и j
такие большие насколько это возможно. Таким образом, оценка этой опции составляет best[j] + g[k].score
.
(Обратите внимание на оптимальные подструктуры и перекрывающиеся компоненты подзадач динамического программирования, воплощенные в приведенном выше уравнении).
Общий ответ на вопрос: best[N]
, то есть лучший результат, который мы можем получить, когда нам разрешено использовать все гены. Ой, я сказал гены? Я имею в виду интервалы.
Это O(N log N)
, потому что:
- Сортировка всех интервалов занимает
O(N log N)
- Нахождение
j
для каждого k
равно O(log N)
с использованием бинарного поиска
Если несколько генов могут иметь одинаковые значения stop
, то ничего не изменилось: вам все равно придется искать самый правый j
. Например, Python это легко с bisect_right
. В Java, где стандартная библиотека двоичного поиска не гарантирует, какой индекс возвращается в случае связей, вы можете (среди многих вариантов) следовать за ним с помощью линейного поиска (для O(N)
производительности в худшем случае) или другой серии двоичных файлов. выполняет поиск, чтобы найти самый правильный индекс.
Ой, я снова сказал гены? Я имею в виду интервалы.
Похожие вопросы