Изменения

Перейти к: навигация, поиск

Участник:Artem.ustinov/НВП

3073 байта убрано, 23:04, 10 января 2018
Удалил второе утверждение, немного дополнил описание
Предположим, мы знаем такое приближение числа <tex>k</tex> числом <tex>m: m \geqslant k</tex>. Мы обсудим, как найти такое <tex>m</tex> позже.
Во время обработки ключей элементов описанный выше алгоритм <tex>\mathrm{LIS}</tex> работает только с очередью <tex>B</tex> и не зависит от предыдущих элементов последовательности, которые не находятся в очереди. Поэтому, если мы разобьем всю последовательность на блоки из <tex>m</tex> элементов (последний блок может быть меньше), и нам удастся обрабатывать каждый как перестановку из <tex>m</tex> элементов за счёт переименовывания элементов, сохраняя очередь <tex>B</tex> для вычисленных ранее блоков, то мы получим асимптотическое время <tex>O(n \operatorname{log} \operatorname{log} (k + m))</tex>, а так как <tex>m \geqslant k</tex>, то <tex>O(n \operatorname{log} \operatorname{log} m)</tex>. (Мы будем обрабатывать блоки последовательно, т.е. с предыдущего блока у нас может остаться <tex>k</tex> значений в очереди, которые дополняются <tex>m</tex> значениями очередного блока — получаем верхнее ограничение в <tex>k + m</tex> обрабатываемых возможных значений.)
=== Деление на блоки===
Определим ключи элементов так, чтобы их значения были в промежутке <tex>\{1,2,\dots,2m\}</tex>. Работая с блоком <tex>C_j</tex>, будем сливать элементы, ключи которых находятся в очереди <tex>B</tex>, с <tex>C_j^s</tex> в список <tex>\mathtt{merged}</tex>. Поскольку мы предположили, что <tex>m\geqslant k</tex>, то количество ключей в <tex>B</tex> не больше <tex>m</tex>, тогда длина <tex>\mathtt{merged}</tex> не больше <tex>2m</tex>, что позволяет однозначно определить ключи на множестве <tex>\{1,2,\dots,2m\}</tex>. Как было замечено ранее, элементы, чьи ключи находятся в <tex>B</tex>, располагаются в возрастающем порядке, поэтому возможно производить тривиальную операцию [[Сортировка слиянием#Принцип работы#Слияние двух массивов | слияния]] за <tex>O(m)</tex>.
В итоге, получим отсортированный список <tex>\mathtt{merged}</tex>, поэтому если сопоставить . Сопоставим ключ каждому элементу как его позицию в этом списке, то тогда справедливо утверждение, что <tex>(\pi_{i}<\pi_{k} \Longleftrightarrow \mathtt{key}(\pi_{i})<\mathtt{key}(\pi_{k}))</tex>, где <tex>\pi_{i},\pi_{k}\in \mathtt{merged}</tex>, поэтому любая возрастающая последовательность ключей элементов будет соответствовать возрастающей последовательности элементов. Таким образом, приоритетная очередь сможет корректно работать с ключами элементов.
После того, как мы определили новые ключи для элементов, обновляем ключи в очереди <tex>B</tex>.
* Вставляем в <tex>B</tex> новые ключи элементов списка <tex>\mathtt{elems}</tex>.
* Обрабатываем ключи элементов блока в порядке исходной последовательности с помощью алгоритма <tex>\mathrm{LIS}</tex>. Для восстановления НВП также используем массив "предшественников", который будет работать с соответствующими ключам элементами <tex>\mathtt{elt}(x)</tex>.
 
=== Доказательство оптимальности ===
{{
Утверждение|statement=
Пусть имеется последовательность <tex>S=\{\pi_1,~\dots,~\pi_n\}</tex>, разбитая на <tex>\lceil n/m \rceil</tex> блоков <tex>C_i</tex> длины <tex>m</tex>. В результате описанного выше алгоритма получается очередь <tex>B</tex>, размер которой равен длине НВП последовательности <tex>S</tex>.
|proof=
Докажем, что перед обработкой блока и после его обработки сохраняется инвариант, что очередь <tex>B</tex> хранит ключи наилучших элементов для всех возможных длин возрастающих подпоследовательностей обработанной последовательности элементов.
* Пусть перед обработкой блока <tex>C_i</tex> соблюдается описанное выражение инварианта для последовательности <tex>S_{(i-1)m}=\{\pi_1,~\dots,~\pi_{(i-1)m}\}</tex>.
* После слияния элементов очереди <tex>B</tex> и блока <tex>C_i^s</tex> получаем отсортированный список <tex>\mathtt{merged}</tex>. Так как <tex>(\pi_{j}<\pi_{k} \Longleftrightarrow \mathtt{key}(\pi_{j})<\mathtt{key}(\pi_{k}))</tex>, где <tex>\pi_{j},\pi_{k}\in \mathtt{merged}</tex>, то справедливо утверждение, что любая возрастающая последовательность ключей элементов будет соответствовать возрастающей последовательности элементов.
* Так как на каждой итерации алгоритма <tex>\mathrm{LIS}</tex> сохраняется выражение инварианта, [[#proposal1|описанное выше]], то в результате работы <tex>\mathrm{LIS}</tex> будет очередь <tex>B</tex> с ключами, соответствующими наилучшим элементам всех возможных длин возрастающих подпоследовательностей последовательности <tex>S_{im}</tex>.
* Таким образом, после обработки последнего блока, в очереди <tex>B</tex> будут храниться ключи наилучших элементов для каждой длины возрастающих подпоследовательностей последовательности <tex>S_n=S</tex>. Тогда последний элемент в очереди <tex>B</tex> соответствует наилучшему элементу длины НВП последовательности <tex>S</tex>, а так как в очереди <tex>B</tex> хранятся наилучшие элементы всех возможных длин возрастающих подпоследовательностей <tex>S</tex>, то размер очереди <tex>B</tex> равен длине НВП последовательности <tex>S</tex>.
}}
===Пример===
76
правок

Навигация