Я пытаюсь понять алгоритм, который дает мне количество увеличивающихся подпоследовательностей длины K в массиве за время O (nКвойти (п)). Я знаю, как решить эту самую проблему, используя алгоритм O (k * n ^ 2). Я посмотрел и обнаружил, что это решение использует BIT (Fenwick Tree) и DP. Я также нашел некоторый код, но я не смог его понять.
Вот некоторые ссылки, которые я посетил, которые были полезны.
Здесь, в ТАК
Topcoder форум
Случайная веб-страница
Я был бы очень признателен, если бы кто-нибудь помог мне понять этот алгоритм.
Я воспроизводю свой алгоритм из Вот, где объясняется его логика:
dp[i, j] = same as before num[i] = how many subsequences that end with i (element, not index this time)
have a certain length
for i = 1 to n do dp[i, 1] = 1
for p = 2 to k do // for each length this time num = {0}
for i = 2 to n do
// note: dp[1, p > 1] = 0
// how many that end with the previous element
// have length p - 1
num[ array[i - 1] ] += dp[i - 1, p - 1] *1*
// append the current element to all those smaller than it
// that end an increasing subsequence of length p - 1,
// creating an increasing subsequence of length p
for j = 1 to array[i] - 1 do *2*
dp[i, p] += num[j]
Вы можете оптимизировать *1*
а также *2*
используя деревья сегментов или деревья с двоичными индексами. Они будут использованы для эффективной обработки следующих операций на num
массив:
(x, v)
добавлять v
в num[x]
(актуально для *1*
);x
найти сумму num[1] + num[2] + ... + num[x]
(актуально для *2*
).Это тривиальные проблемы для обеих структур данных.
Замечания: Это будет иметь сложность O(n*k*log S)
, где S
верхняя граница значений в вашем массиве. Это может или не может быть достаточно хорошим. Сделать это O(n*k*log n)
Вам нужно нормализовать значения вашего массива перед запуском вышеуказанного алгоритма. Нормализация означает преобразование всех значений массива в значения, меньшие или равные n
, Итак, это:
5235 223 1000 40 40
становится:
4 2 3 1 1
Это можно сделать с помощью сортировки (сохраните исходные индексы).
Других решений пока нет …