Я много думал о следующей проблеме:
Нам дан массив из n чисел.Мы начинаем с первого индекса, и наша задача - добраться до последнего индекса.Каждое движение мы можем сделать один или два шага вперед, и число в индексе, к которому мы переходим, отражает стоимость, которую мы должны заплатить за посещение этого индекса.Нам нужно найти самый дешевый способ добраться до конца массива.
Например, если массив выглядит так: [2,1,4,2,5] самый дешевыйдо конца можно добраться до 10: мы посещаем индексы 1-> 2-> 4-> 5 и должны заплатить 2 + 1 + 2 + 5 = 10 , чтоэто самый дешевый способ.Пусть f (i) будет самой дешевой ценой для индекса i .Это мы можем легко вычислить за O (n) время с помощью динамического программирования, поняв, что f (i) = arr [i] + min (f (i-1), f (i-2)))
Но вот поворот: массив обновляется несколько раз, и после каждого обновления мы должны быть в состоянии сказать в O (logn) время, что является самым дешевым способомв данный момент.Обновление массива происходит путем указания индекса, который будет изменен, и номера, на который он будет изменен.Например, обновление может быть arr [2] = 7 , изменяя наш примерный массив на [2,7,4,2,5] .Теперь самый дешевый способ будет 11.
Теперь, как мы можем поддержать эти обновления в O (logn) времени?Есть идеи?
Вот то, что я до сих пор придумал: во-первых, я бы создал массив f для динамического программирования, как описано ранее.Я бы сохранил содержимое этого массива в дереве сегментов s следующим образом: s (i) = f (i) - f (i-1) .Это позволило бы мне обновлять интервалы f (добавляя константу к каждому значению) за O (logn) времени и запрашивать значения по данному индексу в O (logn) время.Это может пригодиться, поскольку после некоторых обновлений часто случается так, что все значения в f необходимо будет увеличивать на постоянную после некоторого заданного индекса в f .Поэтому, запрашивая значение s (n) в дереве сегментов после каждого обновления, мы получим нужный нам ответ.
Однако после обновления могут произойти разные вещи:
- Необходимо обновить только одно значение в f .Например, если [2,1,4,2,5,4,9,3,7] изменяется на [2,1,9,2,5,4,9,3, 7] only f (3) необходимо будет обновить, так как в любом случае ни один из самых дешевых способов не прошел 3. индекс.
- Все значения в f после того, как данный индекс необходимо обновить константой.Это то, для чего подходит дерево сегментов.
- Каждое другое значение в f после того, как данный индекс должен быть обновлен константой.
- Нечто более случайное.