Каков самый быстрый алгоритм для такого рода RMQ?

Делаю задачу по следующему алгоритму (псевдокод)

int A = []
int C = { ... } // N non-negative integers 
int R = { ... } // N non-negative integers
for(i = 0 to N){
    // Let j in range [i-R[i], i-1]
    A[i] = Minimum of ( A[j] + C[j] ) where j in [i-R[i], i-1]
}

Что пытается сделать цикл, так это использовать диапазон предыдущих вычислений A[j] для вычисления текущего A[i].

Для меня это похоже на выполнение N динамических RMQ (минимальный запрос диапазона).

Он динамический, потому что мы заранее не знаем значение A, мы вычисляем его онлайн, используя ранее вычисленные значения.


Например,

C = {10,1,5,3}
R = {2,4,2,3}

A[0] = C[0] // Assume for i = 0, this is always true as base case
A[1] = Min(A[j] + C[j]) where -3 <= j <= 0, only j = 0 is valid option
     = Min(A[0] + C[0]) = 20
A[2] = Min(A[j] + C[j]) where 1 <= j <= 1
     = 21
A[3] = Min(A[j] + C[j]) where -1 <= j <= 2
     = Min(A[0]+C[0], A[1]+C[1], A[2]+C[2])
     = Min(20, 21, 24)
     = 20

Итак, мой вопрос: есть ли какой-либо алгоритм, который быстрее, чем O(N^2), для достижения этого? Я чувствую, что есть какой-то метод/структура данных для ускорения N RMQ, но я не знаю, как это сделать.

Пожалуйста, скажите мне, чтобы уточнить, если пример не ясен.


person shole    schedule 29.09.2017    source источник


Ответы (1)


динамическая задача RMQ — это базовое применение дерева сегментов со сложностью O(log n) на запрос.

person Laney    schedule 29.09.2017