<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Max+27</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Max+27"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Max_27"/>
		<updated>2026-06-11T20:00:50Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=59132</id>
		<title>Задача о наибольшей общей возрастающей последовательности</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=59132"/>
				<updated>2017-01-07T15:40:16Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Исправил замечания&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон: Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Даны два массива: &amp;lt;tex&amp;gt; a[1..n] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..m] &amp;lt;/tex&amp;gt;. Требуется найти их ''наибольшую общую возрастающую подпоследовательность (НОВП).''}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
'''Наибольшая общая возрастающая подпоследовательность, НОВП''' (англ. ''longest common increasing subsequence, LCIS'')  массива &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; и массива &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; — это последовательность &amp;lt;tex&amp;gt; X = \left \langle x_1, x_2, \ldots, x_k \right \rangle &amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt; x_1 &amp;lt; x_2 &amp;lt; \ldots &amp;lt; x_k &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; X &amp;lt;/tex&amp;gt; является ''подпоследовательностью'' &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; &amp;amp;#215; m&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Построим следующую динамику: &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это длина наибольшей возрастающей подпоследовательности массивов &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, последний элемент которой &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] (a[i] = b[j]) &amp;lt;/tex&amp;gt;. Будем заполнять &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, а при равенстве по увеличению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Ответом на задачу будет максимум из всех элементов &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; (где &amp;lt;tex&amp;gt; i = 1...n &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; j = 1...m. &amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Заполнять &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; будем следующим образом: на очередном шаге сравниваем элементы &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt; d[i][j] = 0 &amp;lt;/tex&amp;gt; (так как нет НОВП, оканчивающейся в разных элементах).&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то эти элементы могут быть частью НОВП. Переберём, какие элементы стояли перед ними в массивах &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;. Заметим, что предыдущие значения &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; уже известны, тогда очередное значение &amp;lt;tex dpi=&amp;quot;130&amp;quot;&amp;gt; d[i][j] = \max\limits_{k = 1..i-1 \atop l = 1..j-1} d[k][l] + 1 &amp;lt;/tex&amp;gt; при условии, что &amp;lt;tex&amp;gt; a[k] = b[l]. &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Длина НОВП будет в элементе с максимальным значением &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt;. Для восстановления подпоследовательности можно хранить массив предков &amp;lt;tex&amp;gt; prev[1..n] &amp;lt;/tex&amp;gt; массива &amp;lt;tex&amp;gt; a: prev[i] &amp;lt;/tex&amp;gt; {{---}} индекс предыдущего элемента НОВП, которая оканчивается в &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''vector&amp;lt;int&amp;gt;''' LCIS(a: '''int[n]''', b: '''int[m]''')&lt;br /&gt;
   '''for''' i = 1 '''to''' n &lt;br /&gt;
     '''for''' j = 1 '''to''' m&lt;br /&gt;
       '''if''' a[i] == b[j]&lt;br /&gt;
         d[i][j] = 1 &amp;lt;font color=green&amp;gt; // НОВП как минимум 1, состоит из одного элемента a[i] &amp;lt;-&amp;gt; b[j] &amp;lt;/font&amp;gt;&lt;br /&gt;
         '''for''' k = 1 '''to''' i - 1&lt;br /&gt;
           '''for''' l = 1 '''to''' j - 1&lt;br /&gt;
             '''if''' a[k] == b[l] '''and''' a[k] &amp;lt; a[i] '''and''' d[i][j] &amp;lt; d[k][l] + 1&lt;br /&gt;
               d[i][j] = d[k][l] + 1&lt;br /&gt;
               prev[i] = k&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление&amp;lt;/font&amp;gt;&lt;br /&gt;
   b_i = 1&lt;br /&gt;
   b_j = 1&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     '''for''' j = 1 '''to''' m &lt;br /&gt;
       '''if''' d[b_i][b_j] &amp;lt; d[i][j]&lt;br /&gt;
         b_i = i&lt;br /&gt;
         b_j = j&lt;br /&gt;
   pos = b_i &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву a, выписывая элементы НОВП&amp;lt;/font&amp;gt;&lt;br /&gt;
   answer: '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(a[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(n&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; &amp;amp;#215; m)==&lt;br /&gt;
Улучшим предыдущее решение. Пусть теперь &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} динамика, в которой элемент &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; по-прежнему последний представитель НОВП массива &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; может не быть быть последним представителем массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, будем &amp;quot;протаскивать&amp;quot; последнее удачное сравнение в динамике: &amp;lt;tex&amp;gt; d[i][j] = d[i][j-1] &amp;lt;/tex&amp;gt; (понять это можно так: &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt; , поэтому &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; не последний представитель НОВП из массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, а значит предыдущий элемент НОВП находится в префиксе &amp;lt;tex&amp;gt; b[1..j-1] &amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt; d[i][j-1] &amp;lt;/tex&amp;gt; уже посчитан).&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то одним дополнительным циклом пробежим по &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и найдём предыдущий элемент НОВП, оканчивающейся в &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; (он меньше &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt;). Из подходящих элементов выберем тот, для которого &amp;lt;tex&amp;gt; d[k][j] &amp;lt;/tex&amp;gt; {{---}} максимальна.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi=&amp;quot;120&amp;quot;&amp;gt; d[i][j] = \max\limits_{k = 1..i-1} d[k][j] + 1 &amp;lt;/tex&amp;gt; при условии, что &amp;lt;tex&amp;gt; a[k] &amp;lt; a[i].&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Длина НОВП будет в элементе с максимальным значением &amp;lt;tex&amp;gt; d[i][m] &amp;lt;/tex&amp;gt;. Для восстановления ответа будем хранить массив предков по массиву &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;, как и в предыдущем решении.&lt;br /&gt;
&lt;br /&gt;
 '''vector&amp;lt;int&amp;gt;''' LCIS(a: '''int[n]''', b: '''int[m]''')&lt;br /&gt;
   '''for''' i = 1 '''to''' n &lt;br /&gt;
     '''for''' j = 1 '''to''' m&lt;br /&gt;
       '''if''' a[i] == b[j]&lt;br /&gt;
         d[i][j] = 1 &amp;lt;font color=green&amp;gt;// НОВП как минимум 1, состоит из одного элемента a[i] &amp;lt;-&amp;gt; b[j]&amp;lt;/font&amp;gt;&lt;br /&gt;
         '''for''' k = 1 '''to''' i - 1&lt;br /&gt;
           '''if''' a[k] &amp;lt; a[i] '''and''' d[i][j] &amp;lt; d[k][j] + 1&lt;br /&gt;
             d[i][j] = d[k][j] + 1&lt;br /&gt;
             prev[i] = k&lt;br /&gt;
       '''else'''&lt;br /&gt;
         d[i][j] = d[i][j - 1] &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление&amp;lt;/font&amp;gt;&lt;br /&gt;
   pos = 1 &amp;lt;font color=green&amp;gt;// ищем элемент c максимальным d[pos][m]&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     '''if''' d[pos][m] &amp;lt; d[i][m]&lt;br /&gt;
       pos = i&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву a, выписывая элементы НОВП&amp;lt;/font&amp;gt; &lt;br /&gt;
   answer: '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(a[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(n &amp;amp;#215; m)==&lt;br /&gt;
Модифицируем предыдущее решение, добавив небольшую ''хитрость''. Теперь &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это длина наибольшей общей возрастающей подпоследовательности префиксов &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;, причем элемент &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последний представитель НОВП массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; может не быть последним в массиве &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;. Вычислять &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; будем всё так же: сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, а при равенстве {{---}} по увеличению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Тогда для очередного значения &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; есть два варианта:&lt;br /&gt;
*&amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; не входит в НОВП. Тогда &amp;lt;tex&amp;gt; d[i][j] = d[i-1][j] &amp;lt;/tex&amp;gt;: значение динамики уже посчитано на префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
*&amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; входит в НОВП. Это значит, что &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то есть для подсчёта &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; нужно пробегать циклом по &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt; в поисках элемента &amp;lt;tex&amp;gt; b[k] &amp;lt; b[j] &amp;lt;/tex&amp;gt; с наибольшим значением &amp;lt;tex&amp;gt; d[i-1][k] &amp;lt;/tex&amp;gt;. Но мы считаем &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, поэтому будем считать &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; ''фиксированным''. Чтобы не запускать цикл при каждом равенстве &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; элементу &amp;lt;tex&amp;gt; b[k] &amp;lt;/tex&amp;gt;, в дополнительной переменной &amp;lt;tex&amp;gt; best &amp;lt;/tex&amp;gt; будем хранить &amp;quot;лучший&amp;quot; элемент (и его индекс &amp;lt;tex&amp;gt; ind &amp;lt;/tex&amp;gt; в массиве &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;) такой, что этот элемент строго меньше &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; (а также меньше &amp;lt;tex&amp;gt; b[k] &amp;lt;/tex&amp;gt;) и значение динамики для него максимально: &amp;lt;tex&amp;gt; b[ind] &amp;lt; a[i] = b[k] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; best = d[i-1][ind] \rightarrow max. &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 '''vector&amp;lt;int&amp;gt;''' LCIS(a: '''int[n]''', b: '''int[m]''')&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     ind = 0 &amp;lt;font color=green&amp;gt;// позиция &amp;quot;лучшего&amp;quot; элемента в массиве b&amp;lt;/font&amp;gt;&lt;br /&gt;
     best = 0 &amp;lt;font color=green&amp;gt;// значение динамики для &amp;quot;лучшего&amp;quot; элемента&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' j = 1 '''to''' m	&lt;br /&gt;
       d[i][j] = d[i - 1][j] &amp;lt;font color=green&amp;gt;// НОВП на a[1..i - 1] и b[1..j] (без элемента a[i])&amp;lt;/font&amp;gt;&lt;br /&gt;
       '''if''' a[i] == b[j] '''and''' d[i - 1][j] &amp;lt; best + 1 &amp;lt;font color=green&amp;gt;// используем a[i]-й элемент для увеличения НОВП&amp;lt;/font&amp;gt;&lt;br /&gt;
         d[i][j] = best + 1                         &lt;br /&gt;
         prev[j] = ind                            &lt;br /&gt;
       '''if''' a[i] &amp;gt; b[j] '''and''' d[i - 1][j] &amp;gt; best &amp;lt;font color=green&amp;gt;// при следующем равенстве a[i] == b[j']&amp;lt;/font&amp;gt;&lt;br /&gt;
         best = d[i - 1][j] &amp;lt;font color=green&amp;gt;// в best будет храниться &amp;quot;лучший&amp;quot; элемент&amp;lt;/font&amp;gt;         &lt;br /&gt;
         ind = j &amp;lt;font color=green&amp;gt;// b[ind] &amp;lt; b[j'] и d[i][ind] &amp;lt;tex&amp;gt; \rightarrow &amp;lt;/tex&amp;gt; max&amp;lt;/font&amp;gt; &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление (по массиву b)&amp;lt;/font&amp;gt;&lt;br /&gt;
   pos = 1 &amp;lt;font color=green&amp;gt;// ищем лучший элемент d[n][pos] &amp;lt;tex&amp;gt; \rightarrow &amp;lt;/tex&amp;gt; max&amp;lt;/font&amp;gt; &lt;br /&gt;
   '''for''' j = 1 '''to''' m&lt;br /&gt;
     '''if''' d[n][pos] &amp;lt; d[n][j]&lt;br /&gt;
       pos = j&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву b, выписывая элементы НОВП&amp;lt;/font&amp;gt; &lt;br /&gt;
   answer: '''vector&amp;lt;int&amp;gt;'''&lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(b[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
=== Доказательство оптимальности ===&lt;br /&gt;
В данной задаче используется принцип оптимальности на префиксе. Использование дополнительной переменной для подсчета всех случаев &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt; не влияет на корректность алгоритма {{---}} это всего лишь уловки реализации. Поэтому покажем, что для вычисления очередного значения &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; мы используем оптимальность на подзадачах и обращаемся к уже посчитанным значениям. &lt;br /&gt;
Напомним, как обозначается динамика: &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это НОВП на префиксах &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;, где последним элементом НОВП является элемент &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; может не быть равен &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; (то есть элемент &amp;lt;tex&amp;gt; a[i'] = b[j] &amp;lt;/tex&amp;gt; лежит где-то в префиксе &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt;). Итак, для &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; есть два варианта:&lt;br /&gt;
* &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; не влияет на результат, и последний элемент НОВП &amp;lt;tex&amp;gt; a[i'] = b[j] &amp;lt;/tex&amp;gt;  лежит в &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последние элементы НОВП префиксов &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} по определению динамики, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; как элемент, который может стать последним, не ухудшая результат. Действительно, последовательность строго возрастает, поэтому если в префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; есть элемент &amp;lt;tex&amp;gt; a[k] = b[j] &amp;lt;/tex&amp;gt;, то его можно заменить на элемент &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; без уменьшения длины НОВП. Если же в &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; такого элемента нет, то &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; {{---}} единственный из возможных вариантов. Итак, &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последние элементы НОВП. Значит, начало НОВП (&amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt;) лежит в префиксах &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j-1] &amp;lt;/tex&amp;gt; (значения для которых уже посчитаны). Мы ищем элемент &amp;lt;tex&amp;gt; b[k] &amp;lt; b[j] &amp;lt;/tex&amp;gt; с лучшей динамикой &amp;lt;tex&amp;gt; d[i-1][k] &amp;lt;/tex&amp;gt;, что удовлетворяет условию возрастания последовательности и автоматически гарантирует, что конец такой НОВП лежит в префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
&lt;br /&gt;
*[[Задача о наибольшей общей подпоследовательности]]&lt;br /&gt;
*[[Задача о наибольшей возрастающей подпоследовательности]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
* [http://codeforces.ru/contest/10/problem/D Codeforces {{---}} Задача о наибольшей общей возрастающей подпоследовательности]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;br /&gt;
[[Категория:Другие задачи]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=59120</id>
		<title>Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=59120"/>
				<updated>2017-01-07T15:09:24Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение &lt;br /&gt;
| definition =&lt;br /&gt;
'''[[Оптимальный префиксный код с длиной кодового слова не более L бит|Оптимальный префиксный код]] с сохранением порядка''' (англ. ''order-preserving code'', ''alphabetic code'').&lt;br /&gt;
&lt;br /&gt;
Пусть у нас есть алфавит &amp;lt;tex&amp;gt; \Sigma &amp;lt;/tex&amp;gt;. Каждому символу &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; сопоставим его код &amp;lt;tex&amp;gt; p_i &amp;lt;/tex&amp;gt;. Кодирование называется оптимальным префиксным с сохранением порядка (алфавитным), если соблюдаются:&lt;br /&gt;
# Условие порядка {{---}} &amp;lt;tex&amp;gt; \forall i, j : c_i &amp;lt; c_j \iff p_i &amp;lt; p_j &amp;lt;/tex&amp;gt;. То есть, если символ &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; лексикографически меньше символа &amp;lt;tex&amp;gt; c_j &amp;lt;/tex&amp;gt;, его код также будет [[лексикографический порядок | лексикографически]] меньше, и наоборот.&lt;br /&gt;
# Условие оптимальности {{---}} &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^{|\Sigma|} f_i \cdot |p_i| &amp;lt;/tex&amp;gt; {{---}} минимально, где &amp;lt;tex&amp;gt; f_i &amp;lt;/tex&amp;gt; {{---}} частота встречаемости символа &amp;lt;tex&amp;gt; c_i &amp;lt;/tex&amp;gt; в тексте, а &amp;lt;tex&amp;gt; |p_i| &amp;lt;/tex&amp;gt; {{---}} длина его кода.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__TOC__ &lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Решим задачу, используя ДП на подотрезках. Пусть в ячейке &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; хранится минимальная стоимость кодового дерева для отрезка алфавита от &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда пересчет &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; будет происходить так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D[i][j] = \min\limits_{k = i}^{j - 1} \left ( D[i][k] + D[k + 1][j] \right ) + w[i][j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Базой динамики будет &amp;lt;tex&amp;gt; D[i][i] = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Добавочный член &amp;lt;tex&amp;gt;w[i][j] = \sum\limits_{t = i}^{j} f_t &amp;lt;/tex&amp;gt; возникает от того что каждым объединением двух подотрезков мы увеличиваем высоту дерева на &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;, а значит, и длины всех кодов символов &amp;lt;tex&amp;gt; c_i .. c_j &amp;lt;/tex&amp;gt; также увеличиваются на &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда такое ''наибольшее'' &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, на котором достигается этот минимум, называется точкой разреза для отрезка &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;. Пусть в ячейке &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; хранится точка разреза на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если разрез происходит по какому-то определенному индексу &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; , такой разрез обозначим &amp;lt;tex&amp;gt; D_q[i][j] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, получили алгоритм, работающий за &amp;lt;tex&amp;gt; O(n^3) &amp;lt;/tex&amp;gt;. Коды каждого символа можно легко получить так же, как в алгоритме Хаффмана {{---}} обходом по построенному дереву.&lt;br /&gt;
&lt;br /&gt;
Если доказать монотонность точки разреза, то можно уменьшить асимптотику алгоритма до &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Монотонность точки разреза ==&lt;br /&gt;
Для доказательства этого сперва докажем несколько лемм.&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
| definition=&lt;br /&gt;
Функция &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; удовлетворяет '''неравенству четырехугольника''' (англ. ''quadrangle inequation''), если&lt;br /&gt;
: &amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : a[i][j] + a[i'][j'] \leqslant a[i'][j] + a[i][j']&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
&amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника.&lt;br /&gt;
| proof=&lt;br /&gt;
Заметим, что &amp;lt;tex&amp;gt; w[i][j] = w[i][t] + w[t+1][j] &amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt; w[i][j] &amp;lt;/tex&amp;gt; {{---}} простая арифметическая сумма. Тогда:&lt;br /&gt;
: &amp;lt;tex&amp;gt; w[i][j] + w[i'][j'] \leqslant w[i'][j] + w[i][j']&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][i' - 1] + w[i'][j]) + (w[i'][j] + w[j + 1][j']) \leqslant (w[i'][j]) + (w[i][i' - 1] + w[i'][j] + w[j + 1][j']) &amp;lt;/tex&amp;gt;&lt;br /&gt;
Получили &amp;lt;tex&amp;gt; 0 \leqslant 0 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt; также удовлетворяет неравенству четырехугольника, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : D[i][j] + D[i'][j'] \leqslant D[i'][j] + D[i][j'] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
| proof=&lt;br /&gt;
При &amp;lt;tex&amp;gt; i = i' &amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt; j = j' &amp;lt;/tex&amp;gt;, очевидно, неравенство выполняется.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' = j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' = j &amp;lt; j' &amp;lt;/tex&amp;gt;. Тогда неравенство четырехугольника сводится к:&lt;br /&gt;
#: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; k = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \leqslant j &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant w[i][j] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} так как &amp;lt;tex&amp;gt; w[i][j'] \geqslant w[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \geqslant j &amp;lt;/tex&amp;gt; {{---}} аналогичный предыдущему случай.&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' &amp;lt; j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' &amp;lt; j &amp;lt; j' &amp;lt;/tex&amp;gt; &lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; y = R[i'][j] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; z = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \leqslant y &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: Получили &amp;lt;tex&amp;gt; i \leqslant z \leqslant y \leqslant j &amp;lt;/tex&amp;gt;. Запишем:&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i'][j'] + D[i][j] \leqslant D_y[i'][j'] + D_z[i][j] = w[i'][j'] + D[i'][y-1] + D[y][j'] + w[i][j] + D[i][z-1] + D[z][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[z][j] + D[y][j'] &amp;lt;/tex&amp;gt; {{---}} по неравенству четырехугольника для &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[y][j] + D[z][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] + D[i'][j] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \geqslant y &amp;lt;/tex&amp;gt; доказывается аналогично.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
| about=&lt;br /&gt;
Монотонность точки разреза&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \forall i \leqslant j : R[i][j] \leqslant R[i][j+1] \leqslant R[i+1][j+1] &amp;lt;/tex&amp;gt;.  &lt;br /&gt;
| proof=&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; i = j &amp;lt;/tex&amp;gt; неравенство, очевидно, выполняется. Рассматриваем случай &amp;lt;tex&amp;gt; i &amp;lt; j &amp;lt;/tex&amp;gt; и только случай &amp;lt;tex&amp;gt; R[i][j] \leqslant R[i][j+1] &amp;lt;/tex&amp;gt; (вторая часть доказывается аналогично):&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; {{---}} максимальный индекс, в котором достигается минимум, достаточно показать, что:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: [D_{k'}[i][j] \leqslant D_k[i][j]] \Rightarrow [D_{k'}[i][j+1] \leqslant D_k[i][j+1]] &amp;lt;/tex&amp;gt; {{---}} фактически, это означает что если на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt; разрез оптимальнее по &amp;lt;tex&amp;gt; k' &amp;lt;/tex&amp;gt;, чем по &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, то он также будет оптимальнее и на отрезке &amp;lt;tex&amp;gt; i..j+1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Докажем более сильное неравенство:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: D_k[i][j] - D_{k'}[i][j] \leqslant D_k[i][j+1] - D_{k'}[i][j+1] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D_k[i][j] + D_{k'}[i][j+1] \leqslant D_k[i][j+1] + D_{k'}[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][j] + D[i][k-1] + D[h][j]) + (w[i][j+1] + D[i][k'-1] + D[k][j+1]) \leqslant (w[i][j+1] + D[i][k-1] + D[k][j+1]) + (w[i][j] + D[i][k'-1] + D[k'][j]) &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D[k][j] + D[k'][j+1] \leqslant D[k][j+1] + D[k'][j] &amp;lt;/tex&amp;gt; {{---}} получили неравенство четырехугольника для &amp;lt;tex&amp;gt; k \leqslant k' \leqslant j \leqslant j+1 &amp;lt;/tex&amp;gt;, что является верным из предыдущей леммы. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Объяснение квадратичной асимптотики ==&lt;br /&gt;
Рассмотрим матрицу &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt;. Так как отрезки &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; i &amp;gt; j &amp;lt;/tex&amp;gt; мы не рассматриваем, она будет верхнетреугольной. Вначале она будет заполнена так, что &amp;lt;tex&amp;gt; R[i][i] = i &amp;lt;/tex&amp;gt; (так как для отрезка, состоящего из одного элемента, он же и является точкой разреза). Далее, для любого элемента &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; его значения лежат между &amp;lt;tex&amp;gt; R[i][j-1] &amp;lt;/tex&amp;gt; (левый элемент в матрице) и &amp;lt;tex&amp;gt; R[i+1][j] &amp;lt;/tex&amp;gt; (нижний элемент в матрице). Так как мы используем динамику по подотрезкам, то сначала мы рассчитаем &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; для отрезков длины &amp;lt;tex&amp;gt; 2 &amp;lt;/tex&amp;gt;, затем &amp;lt;tex&amp;gt; 3 &amp;lt;/tex&amp;gt;, и так далее до &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;. Фактически, мы будем обходить диагонали матрицы, количество которых равно &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим элемент &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i][j-1] \leqslant R[i][j] \leqslant R[i+1][j] &amp;lt;/tex&amp;gt;. Следующий элемент, который мы будем пересчитывать {{---}} &amp;lt;tex&amp;gt; R[i+1][j+1] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i+1][j] \leqslant R[i+1][j+1] \leqslant R[i+2][j+1] &amp;lt;/tex&amp;gt;. Таким образом, заполняя одну диагональ, алгоритм сделает не более &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; шагов, а так как диагоналей &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;, получили асимптотику &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Источники информации ==&lt;br /&gt;
* [http://www.sciencedirect.com/science/article/pii/S0304397596003209 S.V. Nagaraj {{---}} Tutorial: Optimal binary search trees]&lt;br /&gt;
* ''Кнут Д.Э.'' {{---}} Искусство программирования, том 3. Сортировка и поиск. — М.: «Вильямс», 2005, стр. 486 - 488&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;br /&gt;
[[Категория:Способы оптимизации методов динамического программирования]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=59118</id>
		<title>Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=59118"/>
				<updated>2017-01-07T15:07:49Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Исправил замечания&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение &lt;br /&gt;
| definition =&lt;br /&gt;
'''[[Оптимальный префиксный код с длиной кодового слова не более L бит|Оптимальный префиксный код]] с сохранением порядка''' (англ. ''order-preserving code'', ''alphabetic code'').&lt;br /&gt;
&lt;br /&gt;
Пусть у нас есть алфавит &amp;lt;tex&amp;gt; \Sigma &amp;lt;/tex&amp;gt;. Каждому символу &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; сопоставим его код &amp;lt;tex&amp;gt; p_i &amp;lt;/tex&amp;gt;. Кодирование называется оптимальным префиксным с сохранением порядка (алфавитным), если соблюдаются:&lt;br /&gt;
# Условие порядка {{---}} &amp;lt;tex&amp;gt; \forall i, j : c_i &amp;lt; c_j \iff p_i &amp;lt; p_j &amp;lt;/tex&amp;gt;. То есть, если символ &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; лексикографически меньше символа &amp;lt;tex&amp;gt; c_j &amp;lt;/tex&amp;gt;, его код также будет [[лексикографический порядок | лексикографически]] меньше, и наоборот.&lt;br /&gt;
# Условие оптимальности {{---}} &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^{|\Sigma|} f_i \cdot |p_i| &amp;lt;/tex&amp;gt; {{---}} минимально, где &amp;lt;tex&amp;gt; f_i &amp;lt;/tex&amp;gt; {{---}} частота встречаемости символа &amp;lt;tex&amp;gt; c_i &amp;lt;/tex&amp;gt; в тексте, а &amp;lt;tex&amp;gt; |p_i| &amp;lt;/tex&amp;gt; {{---}} длина его кода.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__TOC__ &lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Решим задачу, используя ДП на подотрезках. Пусть в ячейке &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; хранится минимальная стоимость кодового дерева для отрезка алфавита от &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда пересчет &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; будет происходить так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D[i][j] = \min\limits_{k = i}^{j - 1} \left ( D[i][k] + D[k + 1][j] \right ) + w[i][j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Базой динамики будет &amp;lt;tex&amp;gt; D[i][i] = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Добавочный член &amp;lt;tex&amp;gt;w[i][j] = \sum\limits_{t = i}^{j} f_t &amp;lt;/tex&amp;gt; возникает от того что каждым объединением двух подотрезков мы увеличиваем высоту дерева на &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;, а значит, и длины всех кодов символов &amp;lt;tex&amp;gt; c_i .. c_j &amp;lt;/tex&amp;gt; также увеличиваются на &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда такое ''наибольшее'' &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, на котором достигается этот минимум, называется точкой разреза для отрезка &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;. Пусть в ячейке &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; хранится точка разреза на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если разрез происходит по какому-то определенному индексу &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; , такой разрез обозначим &amp;lt;tex&amp;gt; D_q[i][j] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, получили алгоритм, работающий за &amp;lt;tex&amp;gt; O(n^3) &amp;lt;/tex&amp;gt;. Коды каждого символа можно легко получить так же, как в алгоритме Хаффмана {{---}} обходом по построенному дереву.&lt;br /&gt;
&lt;br /&gt;
Если доказать монотонность точки разреза, то можно уменьшить асимптотику алгоритма до &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Монотонность точки разреза ==&lt;br /&gt;
Для доказательства этого сперва докажем несколько лемм.&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
| definition=&lt;br /&gt;
Функция &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; удовлетворяет '''неравенству четырехугольника''' (англ. ''quadrangle inequation''), если&lt;br /&gt;
: &amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : a[i][j] + a[i'][j'] \leqslant a[i'][j] + a[i][j']&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
&amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника.&lt;br /&gt;
| proof=&lt;br /&gt;
Заметим, что &amp;lt;tex&amp;gt; w[i][j] = w[i][t] + w[t+1][j] &amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt; w[i][j] &amp;lt;/tex&amp;gt; {{---}} простая арифметическая сумма. Тогда:&lt;br /&gt;
: &amp;lt;tex&amp;gt; w[i][j] + w[i'][j'] \leqslant w[i'][j] + w[i][j']&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][i' - 1] + w[i'][j]) + (w[i'][j] + w[j + 1][j']) \leqslant (w[i'][j]) + (w[i][i' - 1] + w[i'][j] + w[j + 1][j']) &amp;lt;/tex&amp;gt;&lt;br /&gt;
Получили &amp;lt;tex&amp;gt; 0 \leqslant 0 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt; также удовлетворяет неравенству четырехугольника, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : D[i][j] + D[i'][j'] \leqslant D[i'][j] + D[i][j'] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
| proof=&lt;br /&gt;
При &amp;lt;tex&amp;gt; i = i' &amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt; j = j' &amp;lt;/tex&amp;gt;, очевидно, неравенство выполняется.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' = j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' = j &amp;lt; j' &amp;lt;/tex&amp;gt;. Тогда неравенство четырехугольника сводится к:&lt;br /&gt;
#: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; k = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \leqslant j &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant w[i][j] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} так как &amp;lt;tex&amp;gt; w[i][j'] \geqslant w[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \geqslant j &amp;lt;/tex&amp;gt; {{---}} аналогичный предыдущему случай.&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' &amp;lt; j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' &amp;lt; j &amp;lt; j' &amp;lt;/tex&amp;gt; &lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; y = R[i'][j] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; z = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \leqslant y &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: Получили &amp;lt;tex&amp;gt; i \leqslant z \leqslant y \leqslant j &amp;lt;/tex&amp;gt;. Запишем:&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i'][j'] + D[i][j] \leqslant D_y[i'][j'] + D_z[i][j] = w[i'][j'] + D[i'][y-1] + D[y][j'] + w[i][j] + D[i][z-1] + D[z][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[z][j] + D[y][j'] &amp;lt;/tex&amp;gt; {{---}} по неравенству четырехугольника для &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[y][j] + D[z][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] + D[i'][j] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \geqslant y &amp;lt;/tex&amp;gt; доказывается аналогично.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
| about=&lt;br /&gt;
Монотонность точки разреза&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \forall i \leqslant j : R[i][j] \leqslant R[i][j+1] \leqslant R[i+1][j+1] &amp;lt;/tex&amp;gt;.  &lt;br /&gt;
| proof=&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; i = j &amp;lt;/tex&amp;gt; неравенство, очевидно, выполняется. Рассматриваем случай &amp;lt;tex&amp;gt; i &amp;lt; j &amp;lt;/tex&amp;gt; и только случай &amp;lt;tex&amp;gt; R[i][j] \leqslant R[i][j+1] &amp;lt;/tex&amp;gt; (вторая часть доказывается аналогично):&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; {{---}} максимальный индекс, в котором достигается минимум, достаточно показать, что:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: [D_{k'}[i][j] \leqslant D_k[i][j]] \Rightarrow [D_{k'}[i][j+1] \leqslant D_k[i][j+1]] &amp;lt;/tex&amp;gt; {{---}} фактически, это означает что если на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt; разрез оптимальнее по &amp;lt;tex&amp;gt; k' &amp;lt;/tex&amp;gt;, чем по &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, то он также будет оптимальнее и на отрезке &amp;lt;tex&amp;gt; i..j+1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Докажем более сильное неравенство:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: D_k[i][j] - D_{k'}[i][j] \leqslant D_k[i][j+1] - D_{k'}[i][j+1] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D_k[i][j] + D_{k'}[i][j+1] \leqslant D_k[i][j+1] + D_{k'}[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][j] + D[i][k-1] + D[h][j]) + (w[i][j+1] + D[i][k'-1] + D[k][j+1]) \leqslant (w[i][j+1] + D[i][k-1] + D[k][j+1]) + (w[i][j] + D[i][k'-1] + D[k'][j]) &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D[k][j] + D[k'][j+1] \leqslant D[k][j+1] + D[k'][j] &amp;lt;/tex&amp;gt; {{---}} получили неравенство четырехугольника для &amp;lt;tex&amp;gt; k \leqslant k' \leqslant j \leqslant j+1 &amp;lt;/tex&amp;gt;, что является верным из предыдущей леммы. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Объяснение квадратичной асимптотики ==&lt;br /&gt;
Рассмотрим матрицу &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt;. Так как отрезки &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; i &amp;gt; j &amp;lt;/tex&amp;gt; мы не рассматриваем, она будет верхнетреугольной. Вначале она будет заполнена так, что &amp;lt;tex&amp;gt; R[i][i] = i &amp;lt;/tex&amp;gt; (так как для отрезка, состоящего из одного элемента, он же и является точкой разреза). Далее, для любого элемента &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; его значения лежат между &amp;lt;tex&amp;gt; R[i][j-1] &amp;lt;/tex&amp;gt; (левый элемент в матрице) и &amp;lt;tex&amp;gt; R[i+1][j] &amp;lt;/tex&amp;gt; (нижний элемент в матрице). Так как мы используем динамику по подотрезкам, то сначала мы рассчитаем &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; для отрезков длины &amp;lt;tex&amp;gt; 2 &amp;lt;/tex&amp;gt;, затем &amp;lt;tex&amp;gt; 3 &amp;lt;/tex&amp;gt;, и так далее до &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;. Фактически, мы будем обходить диагонали матрицы, количество которых равно &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим элемент &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i][j-1] \leqslant R[i][j] \leqslant R[i+1][j] &amp;lt;/tex&amp;gt;. Следующий элемент, который мы будем пересчитывать {{---}} &amp;lt;tex&amp;gt; R[i+1][j+1] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i+1][j] \leqslant R[i+1][j+1] \leqslant R[i+2][j+1] &amp;lt;/tex&amp;gt;. Таким образом, заполняя одну диагональ, алгоритм сделает не более &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; шагов, а так как диагоналей &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;, получили асимптотику &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Источники информации ==&lt;br /&gt;
* [http://www.sciencedirect.com/science/article/pii/S0304397596003209 S.V. Nagaraj {{---}} Tutorial: Optimal binary search trees]&lt;br /&gt;
* ''Кнут Д.Э.'' {{---}} Искусство программирования, том 3. Сортировка и поиск. — М.: «Вильямс», 2005, стр. 486 - 488&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;br /&gt;
[[Категория:Способы оптимизации методов динамического программирования]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=58970</id>
		<title>Категория:Другие задачи динамического программирования</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=58970"/>
				<updated>2017-01-06T17:52:44Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Новая страница: «Категория:Дискретная математика и алгоритмы [[Категория:Динамическое программирован...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%BF%D0%B0%D0%BB%D0%B8%D0%BD%D0%B4%D1%80%D0%BE%D0%BC%D0%BD%D0%BE%D0%B9_%D0%BF%D0%BE%D0%B4%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58969</id>
		<title>Задача о наибольшей общей палиндромной подпоследовательности</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%BF%D0%B0%D0%BB%D0%B8%D0%BD%D0%B4%D1%80%D0%BE%D0%BC%D0%BD%D0%BE%D0%B9_%D0%BF%D0%BE%D0%B4%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58969"/>
				<updated>2017-01-06T17:52:01Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''[[Задача о наибольшей общей подпоследовательности]]''' (англ. ''longest common subsequence (LCS)'') {{---}} классическая и хорошо изученная проблема.&lt;br /&gt;
&lt;br /&gt;
'''[[Задача о наибольшей подпоследовательности-палиндроме]]''' (англ. ''longest palindromic subsequence (LPS)'') {{---}} также хорошо изучена.&lt;br /&gt;
&lt;br /&gt;
Здесь мы рассмотрим задачу, которая объединяет две вышеперечисленные задачи в одну.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Для последовательности &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, мы обозначим её подпоследовательность &amp;lt;tex&amp;gt;x_{i}...x_{j}\ (1 \leqslant i \leqslant j \leqslant n)\ &amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;X_{i,j}&amp;lt;/tex&amp;gt;. Для двух последовательностей &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt;, если общая подпоследовательность &amp;lt;tex&amp;gt;Z&amp;lt;/tex&amp;gt; последовательностей &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt; является палиндромом, то &amp;lt;tex&amp;gt;Z&amp;lt;/tex&amp;gt; называется '''общей подпалиндромной подпоследовательностью''' (англ. ''common palindromic subsequence''). Общая подпалиндромная последовательность, имеющая максимальную длину, называется '''наибольшей общей подпалиндромной подпоследовательностью''' (англ. ''longest common palindromic subsequence (LCPS)'') и мы обозначим её как &amp;lt;tex&amp;gt;LCPS(X,Y)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}{{Задача&lt;br /&gt;
|definition = '''Наибольшая общая подпалиндромная подпоследовательность''' {{---}} задача, являющаяся интересным вариантом классической задачи о поиске наибольшей общей подпоследовательности, которая также накладывает условия, что эта подпоследовательность должна быть палиндромом.&lt;br /&gt;
}}&lt;br /&gt;
==Наивное решение==&lt;br /&gt;
Можно придумать такое решение данной задачи: найти наибольшую общую подпоследовательность, в ней найти наибольшую подпалиндромную подпоследовательность. Но, к сожалению, это решение '''неверно'''.&lt;br /&gt;
===Контрпример===&lt;br /&gt;
Возьмем две последовательности &amp;lt;tex&amp;gt;X=[1,\ 2,\ 3,\ 1]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y=[1,\ 1,\ 2,\ 3]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Наибольшей общая подпоследовательность данных последовательностей равна &amp;lt;tex&amp;gt;LCS(X,Y) = [1,\ 2,\ 3]&amp;lt;/tex&amp;gt; и в ней наибольшая подпалиндромная последовательность имеет длину &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Но очевидно, что на самом деле последовательность &amp;lt;tex&amp;gt;Z=[1,\ 1]&amp;lt;/tex&amp;gt; является наибольшим общей палиндромной подпоследовательностью &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt; и имеет длину &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==Решение с помощью динамического программирования==&lt;br /&gt;
Заметим, что в качестве подзадач для &amp;lt;tex&amp;gt;LCPS&amp;lt;/tex&amp;gt;, в которых мы можем посчитать ответ, логично взять подпоследовательность от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; и от &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt;. Основываясь на этом наблюдении мы сформулируем следующую теорему, которая доказывает оптимальную подструктуру свойств задачи &amp;lt;tex&amp;gt;LCPS&amp;lt;/tex&amp;gt;, что даст возможность воспользоваться идеей [[Динамическое программирование | динамического программирования]].&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Пусть &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt; {{---}} две последовательности длин &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; соответственно, а &amp;lt;tex&amp;gt;X_{i,j}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y_{k,l}&amp;lt;/tex&amp;gt; {{---}} две подпоследовательности последовательностей &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt; соответственно. Пусть &amp;lt;tex&amp;gt;Z = z_{1}z_{2}...z_{u}&amp;lt;/tex&amp;gt; {{---}} наибольшая общая подпалиндромная последовательность двух подпоследовательностей &amp;lt;tex&amp;gt;X_{i,j}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y_{k,l}&amp;lt;/tex&amp;gt;. Тогда выполняются следующие утверждения,&lt;br /&gt;
&lt;br /&gt;
# Если &amp;lt;tex&amp;gt;x_i=x_j=y_k=y_l=a&amp;lt;/tex&amp;gt; (для произвольного &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;), тогда &amp;lt;tex&amp;gt;z_1=z_u=a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Z_{2, u-1}&amp;lt;/tex&amp;gt; {{---}} НОПП от подпоследовательностей &amp;lt;tex&amp;gt;X_{i+1,j-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y_{k+1,l-1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если &amp;lt;tex&amp;gt;x_i=x_j=y_k=y_l&amp;lt;/tex&amp;gt; не выполняется, то &amp;lt;tex&amp;gt;Z&amp;lt;/tex&amp;gt; {{---}} НОПП от подпоследовательностей (&amp;lt;tex&amp;gt;X_{i+1,j}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y_{k,l}&amp;lt;/tex&amp;gt;) или (&amp;lt;tex&amp;gt;X_{i,j-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y_{k,l}&amp;lt;/tex&amp;gt;) или (&amp;lt;tex&amp;gt;X_{i,j}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y_{k+1,l}&amp;lt;/tex&amp;gt;) или (&amp;lt;tex&amp;gt;X_{i,j}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y_{k,l-1}&amp;lt;/tex&amp;gt;).&lt;br /&gt;
}}&lt;br /&gt;
На основании теоремы мы напишем следующую рекурсивную формулу для длины наибольшей общей подпалиндромной подпоследовательности:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
lcps[i,j,k,l] = \left\{\begin{array}{llcl}&lt;br /&gt;
0&amp;amp;&amp;amp;;&amp;amp;i &amp;gt; j\ \lor\ k &amp;gt; l\\&lt;br /&gt;
1&amp;amp;&amp;amp;;&amp;amp;(i = j)\ \land\ (k = l)\ \land\ (x_i=x_j=y_k=y_l)\\&lt;br /&gt;
2+lcps[i+1,j-1,k+1,l-1]&amp;amp;&amp;amp;;&amp;amp;(i &amp;lt; j)\ \land\ (k &amp;lt; l)\ \land\ (x_i=x_j=y_k=y_l)\\&lt;br /&gt;
\max{(}lcps[i+1,j,k,l],lcps[i,j-1,k,l],&amp;amp;&amp;amp;;&amp;amp;(i \leqslant j)\ \land\ (k \leqslant l)\ \land\ \lnot(x_i=x_j=y_k=y_l)\\&lt;br /&gt;
\:\:\:\:\:\:\:\:\:\:\:lcps[i,j,k+1,l],lcps[i,j,k,l-1])&lt;br /&gt;
\end{array}\right.&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Где &amp;lt;tex&amp;gt;lcps[i,j,k,l]&amp;lt;/tex&amp;gt; {{---}} длина наибольшей общей палиндромной подпоследовательности от &amp;lt;tex&amp;gt;X_{i,j}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y_{k,l}&amp;lt;/tex&amp;gt;. Длина наибольшей общей палиндромной подпоследовательности от последовательностей &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt; будет расположена в &amp;lt;tex&amp;gt;lcps[1,n,1,m]&amp;lt;/tex&amp;gt;. Мы можем вычислить эту длину за время &amp;lt;tex&amp;gt;O(n^4)&amp;lt;/tex&amp;gt; используя динамическое программирование.&lt;br /&gt;
&lt;br /&gt;
===Реализация===&lt;br /&gt;
Будем использовать динамику с запоминанием ответа (с мемоизацией). Оформим решения в виде рекурсивной функции &amp;lt;tex&amp;gt;lcps&amp;lt;/tex&amp;gt;, которая возвращает ответ для подзадачи, на которую она была вызвана.&amp;lt;br&amp;gt; В массиве &amp;lt;tex&amp;gt;\mathtt{ans}&amp;lt;/tex&amp;gt; хранятся ответы для подзадач. До запуска функции &amp;lt;tex&amp;gt;lcps&amp;lt;/tex&amp;gt; заполним массив &amp;lt;tex&amp;gt;ans&amp;lt;/tex&amp;gt; значением &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;. Так как каждое значение считается не более одного раза и эта операция происходит за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, мы получим асимптотику &amp;lt;tex&amp;gt;O(n^4)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
 '''int''' lcps(i: '''int''', j: '''int''', k: '''int''', l: '''int''')&lt;br /&gt;
   '''if''' (ans[i][j][k][l] &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; -1) &amp;lt;span style=&amp;quot;color:Green&amp;quot;&amp;gt;// если значение уже посчитано, то надо его вернуть&amp;lt;/span&amp;gt;&lt;br /&gt;
     '''return''' ans[i][j][k][l]&lt;br /&gt;
   '''if''' (i &amp;gt; j '''or''' k &amp;gt; l)&lt;br /&gt;
     ans[i][j][k][l] = 0&lt;br /&gt;
     '''return''' 0&lt;br /&gt;
   '''if''' (X[i] == X[j] == Y[k] == Y[l])&lt;br /&gt;
     '''if''' (i == j '''and''' k == l)&lt;br /&gt;
       ans[i][j][k][l] = 1&lt;br /&gt;
       '''return''' 1       &lt;br /&gt;
     '''else'''   &lt;br /&gt;
       ans[i][j][k][l] = (2 + lcps(i + 1, j - 1, k + 1, l - 1))    &lt;br /&gt;
       '''return''' ans[i][j][k][l]&lt;br /&gt;
   ans[i][j][k][l] = max(lcps(i + 1, j, k, l), lcps(i, j - 1, k, l), lcps(i, j, k + 1, l), lcps(i, j, k, l - 1))&lt;br /&gt;
   '''return''' ans[i][j][k][l]&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Задача о наибольшей возрастающей подпоследовательности]]&lt;br /&gt;
* [[Задача о редакционном расстоянии, алгоритм Вагнера-Фишера]]&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://www.academia.edu/2015585/Computing_a_Longest_Common_Palindromic_Subsequence Academia.edu {{---}} Computing a Longest Common Palindromic Subsequence]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;br /&gt;
[[Категория:Другие задачи]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58968</id>
		<title>Задача о наибольшей общей возрастающей последовательности</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58968"/>
				<updated>2017-01-06T17:50:39Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Исправил замечания&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон: Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Даны два массива: &amp;lt;tex&amp;gt; a[1..n] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..m] &amp;lt;/tex&amp;gt;. Требуется найти их ''наибольшую общую возрастающую подпоследовательность (НОВП).''}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
'''Наибольшая общая возрастающая подпоследовательность, НОВП''' (англ. ''longest common increasing subsequence, LCIS'')  массива &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; и массива &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; — это последовательность &amp;lt;tex&amp;gt; X = \left \langle x_1, x_2, \ldots, x_k \right \rangle &amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt; x_1 &amp;lt; x_2 &amp;lt; \ldots &amp;lt; x_k &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; X &amp;lt;/tex&amp;gt; является ''подпоследовательностью'' &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;4&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Построим следующую динамику: &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это длина наибольшей возрастающей подпоследовательности массивов &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, последний элемент которой &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] (a[i] = b[j]) &amp;lt;/tex&amp;gt;. Будем заполнять &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, а при равенстве по увеличению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Ответом на задачу будет максимум из всех элементов &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; (где &amp;lt;tex&amp;gt; i = 1...n &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; j = 1...m. &amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Заполнять &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; будем следующим образом: на очередном шаге сравниваем элементы &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt; d[i][j] = 0 &amp;lt;/tex&amp;gt; (так как нет НОВП, оканчивающейся в разных элементах).&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то эти элементы могут быть частью НОВП. Переберём, какие элементы стояли перед ними в массивах &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;. Заметим, что предыдущие значения &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; уже известны, тогда очередное значение &amp;lt;tex dpi=&amp;quot;130&amp;quot;&amp;gt; d[i][j] = \max\limits_{k = 1..i-1 \atop l = 1..j-1} d[k][l] + 1 &amp;lt;/tex&amp;gt; при условии, что &amp;lt;tex&amp;gt; a[k] = b[l]. &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Длина НОВП будет в элементе с максимальным значением &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt;. Для восстановления подпоследовательности можно хранить массив предков &amp;lt;tex&amp;gt; prev[1..n] &amp;lt;/tex&amp;gt; массива &amp;lt;tex&amp;gt; a: prev[i] &amp;lt;/tex&amp;gt; {{---}} индекс предыдущего элемента НОВП, которая оканчивается в &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''int[]''' LCIS(a: '''int[n]''', b: '''int[m]''')&lt;br /&gt;
   '''for''' i = 1 '''to''' n &lt;br /&gt;
     '''for''' j = 1 '''to''' m&lt;br /&gt;
       '''if''' a[i] == b[j]&lt;br /&gt;
         d[i][j] = 1 &amp;lt;font color=green&amp;gt; // НОВП как минимум 1, состоит из одного элемента a[i] &amp;lt;-&amp;gt; b[j] &amp;lt;/font&amp;gt;&lt;br /&gt;
         '''for''' k = 1 '''to''' i - 1&lt;br /&gt;
           '''for''' l = 1 '''to''' j - 1&lt;br /&gt;
             '''if''' a[k] == b[l] '''and''' a[k] &amp;lt; a[i] '''and''' d[i][j] &amp;lt; d[k][l] + 1&lt;br /&gt;
               d[i][j] = d[k][l] + 1&lt;br /&gt;
               prev[i] = k&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление&amp;lt;/font&amp;gt;&lt;br /&gt;
   b_i = 1&lt;br /&gt;
   b_j = 1&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     '''for''' j = 1 '''to''' m &lt;br /&gt;
       '''if''' d[b_i][b_j] &amp;lt; d[i][j]&lt;br /&gt;
         b_i = i&lt;br /&gt;
         b_j = j&lt;br /&gt;
   pos = b_i &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву a, выписывая элементы НОВП&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(a[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Улучшим предыдущее решение. Пусть теперь &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} динамика, в которой элемент &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; по-прежнему последний представитель НОВП массива &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; может не быть быть последним представителем массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, будем &amp;quot;протаскивать&amp;quot; последнее удачное сравнение в динамике: &amp;lt;tex&amp;gt; d[i][j] = d[i][j-1] &amp;lt;/tex&amp;gt; (понять это можно так: &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt; , поэтому &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; не последний представитель НОВП из массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, а значит предыдущий элемент НОВП находится в префиксе &amp;lt;tex&amp;gt; b[1..j-1] &amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt; d[i][j-1] &amp;lt;/tex&amp;gt; уже посчитан).&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то одним дополнительным циклом пробежим по &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и найдём предыдущий элемент НОВП, оканчивающейся в &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; (он меньше &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt;). Из подходящих элементов выберем тот, для которого &amp;lt;tex&amp;gt; d[k][j] &amp;lt;/tex&amp;gt; {{---}} максимальна.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi=&amp;quot;120&amp;quot;&amp;gt; d[i][j] = \max\limits_{k = 1..i-1} d[k][j] + 1 &amp;lt;/tex&amp;gt; при условии, что &amp;lt;tex&amp;gt; a[k] &amp;lt; a[i].&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Длина НОВП будет в элементе с максимальным значением &amp;lt;tex&amp;gt; d[i][m] &amp;lt;/tex&amp;gt;. Для восстановления ответа будем хранить массив предков по массиву &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;, как и в предыдущем решении.&lt;br /&gt;
&lt;br /&gt;
 '''int[]''' LCIS(a: '''int[n]''', b: '''int[m]''')&lt;br /&gt;
   '''for''' i = 1 '''to''' n &lt;br /&gt;
     '''for''' j = 1 '''to''' m&lt;br /&gt;
       '''if''' a[i] == b[j]&lt;br /&gt;
         d[i][j] = 1 &amp;lt;font color=green&amp;gt;// НОВП как минимум 1, состоит из одного элемента a[i] &amp;lt;-&amp;gt; b[j]&amp;lt;/font&amp;gt;&lt;br /&gt;
         '''for''' k = 1 '''to''' i - 1&lt;br /&gt;
           '''if''' a[k] &amp;lt; a[i] '''and''' d[i][j] &amp;lt; d[k][j] + 1&lt;br /&gt;
             d[i][j] = d[k][j] + 1&lt;br /&gt;
             prev[i] = k&lt;br /&gt;
       '''else'''&lt;br /&gt;
         d[i][j] = d[i][j - 1] &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление&amp;lt;/font&amp;gt;&lt;br /&gt;
   pos = 1 &amp;lt;font color=green&amp;gt;// ищем элемент c максимальным d[pos][m]&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     '''if''' d[pos][m] &amp;lt; d[i][m]&lt;br /&gt;
       pos = i&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву a, выписывая элементы НОВП&amp;lt;/font&amp;gt; &lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(a[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Модифицируем предыдущее решение, добавив небольшую &amp;quot;хитрость&amp;quot;. Теперь &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это длина наибольшей общей возрастающей подпоследовательности префиксов &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;, причем элемент &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последний представитель НОВП массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; может не быть последним в массиве &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;. Вычислять &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; будем всё так же: сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, а при равенстве {{---}} по увеличению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Тогда для очередного значения &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; есть два варианта:&lt;br /&gt;
*&amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; не входит в НОВП. Тогда &amp;lt;tex&amp;gt; d[i][j] = d[i-1][j] &amp;lt;/tex&amp;gt;: значение динамики уже посчитано на префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
*&amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; входит в НОВП. Это значит, что &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то есть для подсчёта &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; нужно пробегать циклом по &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt; в поисках элемента &amp;lt;tex&amp;gt; b[k] &amp;lt; b[j] &amp;lt;/tex&amp;gt; с наибольшим значением &amp;lt;tex&amp;gt; d[i-1][k] &amp;lt;/tex&amp;gt;. Но мы считаем &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, поэтому будем считать &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; ''фиксированным''. Чтобы не запускать цикл при каждом равенстве &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; элементу &amp;lt;tex&amp;gt; b[k] &amp;lt;/tex&amp;gt;, в дополнительной переменной &amp;lt;tex&amp;gt; best &amp;lt;/tex&amp;gt; будем хранить &amp;quot;лучший&amp;quot; элемент (и его индекс &amp;lt;tex&amp;gt; ind &amp;lt;/tex&amp;gt; в массиве &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;) такой, что этот элемент строго меньше &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; (а также меньше &amp;lt;tex&amp;gt; b[k] &amp;lt;/tex&amp;gt;) и значение динамики для него максимально: &amp;lt;tex&amp;gt; b[ind] &amp;lt; a[i] = b[k] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; best = d[i-1][ind] \rightarrow max. &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 '''int[]''' LCIS(a: '''int[n]''', b: '''int[m]''')&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     ind = 0 &amp;lt;font color=green&amp;gt;// позиция &amp;quot;лучшего&amp;quot; элемента в массиве b&amp;lt;/font&amp;gt;&lt;br /&gt;
     best = 0 &amp;lt;font color=green&amp;gt;// значение динамики для &amp;quot;лучшего&amp;quot; элемента&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' j = 1 '''to''' m	&lt;br /&gt;
       d[i][j] = d[i - 1][j] &amp;lt;font color=green&amp;gt;// НОВП на a[1..i - 1] и b[1..j] (без элемента a[i])&amp;lt;/font&amp;gt;&lt;br /&gt;
       '''if''' a[i] == b[j] '''and''' d[i - 1][j] &amp;lt; best + 1 &amp;lt;font color=green&amp;gt;// используем a[i]-й элемент для увеличения НОВП&amp;lt;/font&amp;gt;&lt;br /&gt;
         d[i][j] = best + 1                         &lt;br /&gt;
         prev[j] = ind                            &lt;br /&gt;
       '''if''' a[i] &amp;gt; b[j] '''and''' d[i - 1][j] &amp;gt; best &amp;lt;font color=green&amp;gt;// при следующем равенстве a[i] == b[j']&amp;lt;/font&amp;gt;&lt;br /&gt;
         best = d[i - 1][j] &amp;lt;font color=green&amp;gt;// в best будет храниться &amp;quot;лучший&amp;quot; элемент&amp;lt;/font&amp;gt;         &lt;br /&gt;
         ind = j &amp;lt;font color=green&amp;gt;// b[ind] &amp;lt; b[j'] и d[i][ind] &amp;lt;tex&amp;gt; \rightarrow &amp;lt;/tex&amp;gt; max&amp;lt;/font&amp;gt; &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление (по массиву b)&amp;lt;/font&amp;gt;&lt;br /&gt;
   pos = 1 &amp;lt;font color=green&amp;gt;// ищем лучший элемент d[n][pos] &amp;lt;tex&amp;gt; \rightarrow &amp;lt;/tex&amp;gt; max&amp;lt;/font&amp;gt; &lt;br /&gt;
   '''for''' j = 1 '''to''' m&lt;br /&gt;
     '''if''' d[n][pos] &amp;lt; d[n][j]&lt;br /&gt;
       pos = j&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву b, выписывая элементы НОВП&amp;lt;/font&amp;gt; &lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(b[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
=== Доказательство оптимальности ===&lt;br /&gt;
В данной задаче используется принцип оптимальности на префиксе. Использование дополнительной переменной для подсчета всех случаев &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt; не влияет на корректность алгоритма {{---}} это всего лишь уловки реализации. Поэтому покажем, что для вычисления очередного значения &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; мы используем оптимальность на подзадачах и обращаемся к уже посчитанным значениям. &lt;br /&gt;
Напомним, как обозначается динамика: &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это НОВП на префиксах &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;, где последним элементом НОВП является элемент &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; может не быть равен &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; (то есть элемент &amp;lt;tex&amp;gt; a[i'] = b[j] &amp;lt;/tex&amp;gt; лежит где-то в префиксе &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt;). Итак, для &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; есть два варианта:&lt;br /&gt;
* &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; не влияет на результат, и последний элемент НОВП &amp;lt;tex&amp;gt; a[i'] = b[j] &amp;lt;/tex&amp;gt;  лежит в &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последние элементы НОВП префиксов &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} по определению динамики, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; как элемент, который может стать последним, не ухудшая результат. Действительно, последовательность строго возрастает, поэтому если в префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; есть элемент &amp;lt;tex&amp;gt; a[k] = b[j] &amp;lt;/tex&amp;gt;, то его можно заменить на элемент &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; без уменьшения длины НОВП. Если же в &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; такого элемента нет, то &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; {{---}} единственный из возможных вариантов. Итак, &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последние элементы НОВП. Значит, начало НОВП (&amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt;) лежит в префиксах &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j-1] &amp;lt;/tex&amp;gt; (значения для которых уже посчитаны). Мы ищем элемент &amp;lt;tex&amp;gt; b[k] &amp;lt; b[j] &amp;lt;/tex&amp;gt; с лучшей динамикой &amp;lt;tex&amp;gt; d[i-1][k] &amp;lt;/tex&amp;gt;, что удовлетворяет условию возрастания последовательности и автоматически гарантирует, что конец такой НОВП лежит в префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
&lt;br /&gt;
*[[Задача о наибольшей общей подпоследовательности]]&lt;br /&gt;
*[[Задача о наибольшей возрастающей подпоследовательности]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
* [http://codeforces.ru/contest/10/problem/D Codeforces {{---}} Задача о наибольшей общей возрастающей подпоследовательности]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;br /&gt;
[[Категория:Другие задачи]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%A1%D0%BF%D0%BE%D1%81%D0%BE%D0%B1%D1%8B_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=58965</id>
		<title>Категория:Способы оптимизации методов динамического программирования</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%A1%D0%BF%D0%BE%D1%81%D0%BE%D0%B1%D1%8B_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F&amp;diff=58965"/>
				<updated>2017-01-06T17:29:45Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Новая страница: «Категория: Дискретная математика и алгоритмы [[Категория:Динамическое программирован...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%B0_%D1%87%D0%B5%D1%82%D1%8B%D1%80%D1%91%D1%85_%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D1%85_%D0%B2_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B0%D1%85_%D0%94%D0%9F_%D0%BD%D0%B0_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B5_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%9D%D0%9E%D0%9F&amp;diff=58963</id>
		<title>Применение метода четырёх русских в задачах ДП на примере задачи о НОП</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%B0_%D1%87%D0%B5%D1%82%D1%8B%D1%80%D1%91%D1%85_%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D1%85_%D0%B2_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B0%D1%85_%D0%94%D0%9F_%D0%BD%D0%B0_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B5_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%9D%D0%9E%D0%9F&amp;diff=58963"/>
				<updated>2017-01-06T17:27:26Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Предподсчёт ===&lt;br /&gt;
Рассмотрим [[Задача о наибольшей общей подпоследовательности|задачу о наибольшей общей подпоследовательности]] для двух последовательностей одинаковой длины. Тогда таблица динамического программирования имеет размер &amp;lt;tex&amp;gt; (n + 1) \times (n + 1) &amp;lt;/tex&amp;gt;. Разобьём её на квадраты размера &amp;lt;tex&amp;gt; k \times k &amp;lt;/tex&amp;gt; следующим образом: выделим каждую &amp;lt;tex&amp;gt; k + 1 &amp;lt;/tex&amp;gt;-ую строчку, начиная с первой. Аналогично выделяем столбцы.&lt;br /&gt;
&lt;br /&gt;
Требуется, чтобы &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; делило &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;, но это не является ограничением - можно дописать в конец последовательностей символы, которые не встречались в других местах этих последовательностей (символы для каждой последовательности должны быть разными). Тогда ответ на задачу не изменится, а длину можно «довести» до делителя &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сделаем предподсчёт действия каждого возможного квадрата. Окончательный результат зависит только от значений в верхнем левом «уголке» над квадратом и подстрок, для которых считается ответ — остальные значения в квадрате однозначно считаются с их помощью. Окончательным результатом будут значения в нижнем правом «уголке» квадрата.&lt;br /&gt;
&lt;br /&gt;
Может показаться, что таких уголков может быть много. Но, так как соседние числа в матрице отличаются не более, чем на один, то результат зависит только от константы в верхнем левом элементе матрицы, и возрастания чисел в верхнем и левом крае квадрата. Возрастание чисел будем хранить с помощью битовых масок: сначала &amp;lt;tex&amp;gt; k - 1 &amp;lt;/tex&amp;gt; бит кодирует возрастание чисел в верхнем крае квадрата (0 - элемент равен предыдущему, 1 - больше предыдущего на один), потом &amp;lt;tex&amp;gt; k - 1 &amp;lt;/tex&amp;gt; бит кодируют возрастание чисел в квадрате по левому краю аналогичным образом.&lt;br /&gt;
&lt;br /&gt;
Более того, константу в верхнем левом элементе квадрата можно вообще не хранить: её можно прибавить при необходимости к каждому элементу результата.&lt;br /&gt;
&lt;br /&gt;
Посчитаем эти квадраты для строк abbabb и bababb. Возьмём &amp;lt;tex&amp;gt; k = 3 &amp;lt;/tex&amp;gt;. Тогда предподсчитанные квадраты, которые понадобятся для дальнейшего вычисления НОП, выглядят так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:4 russians lcs precalc.png]]&lt;br /&gt;
&lt;br /&gt;
=== Вычисление НОП на сжатой матрице ===&lt;br /&gt;
Ответ для самой задачи НОП считается аналогично обычному алгоритму, только рассматривая не каждую ячейку таблицы, а квадраты &amp;lt;tex&amp;gt; k \times k &amp;lt;/tex&amp;gt;. В очередной квадрат (пусть его левый верхний угол находится в ячейке с координатами &amp;lt;tex&amp;gt; i, j &amp;lt;/tex&amp;gt;) вставляем значения предподсчитанного квадрата, соответствующего данным подстрокам и битовым маскам, и прибавляем ко всем элементам в квадрате число, стоящее в уголке над квадратом, т.е. в ячейке с координатами &amp;lt;tex&amp;gt; i - 1, j - 1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для нашего примера итоговая таблица выглядит так:&lt;br /&gt;
&lt;br /&gt;
[[Файл:4 russians lcs table.png]]&lt;br /&gt;
&lt;br /&gt;
== Анализ алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Время работы ===&lt;br /&gt;
При предподсчёте перебирается &amp;lt;tex&amp;gt; | \Sigma | ^k &amp;lt;/tex&amp;gt; (где &amp;lt;tex&amp;gt; | \Sigma | &amp;lt;/tex&amp;gt; — мощность алфавита) возможных подстрок первой строки и столько же — второй строки. Для каждой возможной подстроки обеих строк перебирается по &amp;lt;tex&amp;gt; 2^{k - 1} &amp;lt;/tex&amp;gt; битовых масок. Для самого предподсчёта требуется время &amp;lt;tex&amp;gt; O(k^2) &amp;lt;/tex&amp;gt;. Дальнейший алгоритм поиска НОП требует &amp;lt;tex&amp;gt; O \left ( \frac{n^2}{k^2} \right ) &amp;lt;/tex&amp;gt;. Тогда суммарное время работы алгоритма составляет &amp;lt;tex&amp;gt; O \left ( |\Sigma| ^{2k} \cdot 2^{2k - 2} \cdot k^2 + \frac{n^2}{k^2} \right ) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Понятно, что для получения выигрыша в производительности по сравнению с обычным алгоритмом необходимо, чтобы первое слагаемое не превышало второе. Найдём &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, решив неравенство:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; |\Sigma| ^{2k} \cdot 2^{2k - 2} \cdot k^2 \leqslant \frac{n^2}{k^2} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \left ( 2 | \Sigma | \right ) ^{2k} \cdot \frac{1}{4} \cdot k^4 \leqslant n^2 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \left ( 2 | \Sigma | \right ) ^k \cdot k^2 \leqslant 2n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; k \log {2 | \Sigma |} + 2 \log k \leqslant \log 2 + \log n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пренебрегая &amp;lt;tex&amp;gt; \log k &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \log 2 &amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt; o(k) &amp;lt;/tex&amp;gt;, получаем &amp;lt;tex&amp;gt; k \leqslant \frac{\log n}{1 + \log | \Sigma |}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Используемая память ===&lt;br /&gt;
Для каждого предподсчитанного квадрата хранятся подстроки длиной &amp;lt;tex&amp;gt; 2k &amp;lt;/tex&amp;gt;, битовые маски длиной &amp;lt;tex&amp;gt; 2k &amp;lt;/tex&amp;gt; и результат — нижний «уголок» длины &amp;lt;tex&amp;gt; 2k - 1 &amp;lt;/tex&amp;gt;. Как уже было подсчитано, всего предподсчитывается &amp;lt;tex&amp;gt; |\Sigma| ^{2k} \cdot 2^{2k - 2} &amp;lt;/tex&amp;gt; квадратов. Дальнейший алгоритм требует &amp;lt;tex&amp;gt; O \left ( \frac{n^2}{k^2} \right ) &amp;lt;/tex&amp;gt;, значит, всего требуется &amp;lt;tex&amp;gt; O \left ( |\Sigma| ^{2k} \cdot 2^{2k - 2} \cdot (2k + 2k + 2k - 1) + \frac{n^2}{k^2} \right ) = O \left ( |\Sigma| ^{2k} \cdot 2^{2k - 2} \cdot k + \frac{n^2}{k^2} \right ) &amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* http://pages.cpsc.ucalgary.ca/~pmohasse/private-lcs.pdf&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;br /&gt;
[[Категория:Способы оптимизации методов динамического программирования]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=58961</id>
		<title>Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=58961"/>
				<updated>2017-01-06T17:21:19Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Исправил замечания&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Определение ==&lt;br /&gt;
{{Определение &lt;br /&gt;
| definition =&lt;br /&gt;
'''[[Оптимальный префиксный код с длиной кодового слова не более L бит|Оптимальный префиксный код]] с сохранением порядка''' (англ. ''order-preserving code'', ''alphabetic code'').&lt;br /&gt;
 &lt;br /&gt;
Пусть у нас есть алфавит &amp;lt;tex&amp;gt; \Sigma &amp;lt;/tex&amp;gt;. Каждому символу &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; сопоставим его код &amp;lt;tex&amp;gt; p_i &amp;lt;/tex&amp;gt;. Кодирование называется оптимальным префиксным с сохранением порядка (алфавитным), если соблюдаются:&lt;br /&gt;
# Условие порядка {{---}} &amp;lt;tex&amp;gt; \forall i, j : c_i &amp;lt; c_j \iff p_i &amp;lt; p_j &amp;lt;/tex&amp;gt;. То есть, если символ &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; лексикографически меньше символа &amp;lt;tex&amp;gt; c_j &amp;lt;/tex&amp;gt;, его код также будет [[лексикографический порядок | лексикографически]] меньше, и наоборот.&lt;br /&gt;
# Условие оптимальности {{---}} &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^{|\Sigma|} f_i \cdot |p_i| &amp;lt;/tex&amp;gt; {{---}} минимально, где &amp;lt;tex&amp;gt; f_i &amp;lt;/tex&amp;gt; {{---}} частота встречаемости символа &amp;lt;tex&amp;gt; c_i &amp;lt;/tex&amp;gt; в тексте, а &amp;lt;tex&amp;gt; |p_i| &amp;lt;/tex&amp;gt; {{---}} длина его кода.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Решим задачу, используя ДП на подотрезках. Пусть в ячейке &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; хранится минимальная стоимость кодового дерева для отрезка алфавита от &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда пересчет &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; будет происходить так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D[i][j] = \min\limits_{k = i}^{j - 1} \left ( D[i][k] + D[k + 1][j] \right ) + w[i][j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Базой динамики будет &amp;lt;tex&amp;gt; D[i][i] = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Добавочный член &amp;lt;tex&amp;gt;w[i][j] = \sum\limits_{t = i}^{j} f_t &amp;lt;/tex&amp;gt; возникает от того что каждым объединением двух подотрезков мы увеличиваем высоту дерева на 1, а значит, и длины всех кодов символов &amp;lt;tex&amp;gt; c_i .. c_j &amp;lt;/tex&amp;gt; также увеличиваются на 1.&lt;br /&gt;
&lt;br /&gt;
Тогда такое ''наибольшее'' &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, на котором достигается этот минимум, называется точкой разреза для отрезка &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;. Пусть в ячейке &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; хранится точка разреза на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если разрез происходит по какому-то определенному индексу &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; , такой разрез обозначим &amp;lt;tex&amp;gt; D_q[i][j] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, получили алгоритм, работающий за &amp;lt;tex&amp;gt; O(n^3) &amp;lt;/tex&amp;gt;. Коды каждого символа можно легко получить так же, как в алгоритме Хаффмана {{---}} обходом по построенному дереву.&lt;br /&gt;
&lt;br /&gt;
Если доказать монотонность точки разреза, то можно уменьшить асимптотику алгоритма до &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Монотонность точки разреза ==&lt;br /&gt;
Для доказательства этого сперва докажем несколько лемм.&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
| definition=&lt;br /&gt;
Функция &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; удовлетворяет '''неравенству четырехугольника''' (англ. ''quadrangle inequation''), если&lt;br /&gt;
: &amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : a[i][j] + a[i'][j'] \leqslant a[i'][j] + a[i][j']&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
&amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника.&lt;br /&gt;
| proof=&lt;br /&gt;
Заметим, что &amp;lt;tex&amp;gt; w[i][j] = w[i][t] + w[t+1][j] &amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt; w[i][j] &amp;lt;/tex&amp;gt; {{---}} простая арифметическая сумма. Тогда:&lt;br /&gt;
: &amp;lt;tex&amp;gt; w[i][j] + w[i'][j'] \leqslant w[i'][j] + w[i][j']&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][i' - 1] + w[i'][j]) + (w[i'][j] + w[j + 1][j']) \leqslant (w[i'][j]) + (w[i][i' - 1] + w[i'][j] + w[j + 1][j']) &amp;lt;/tex&amp;gt;&lt;br /&gt;
Получили &amp;lt;tex&amp;gt; 0 \leqslant 0 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt; также удовлетворяет неравенству четырехугольника, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : D[i][j] + D[i'][j'] \leqslant D[i'][j] + D[i][j'] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
| proof=&lt;br /&gt;
При &amp;lt;tex&amp;gt; i = i' &amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt; j = j' &amp;lt;/tex&amp;gt;, очевидно, неравенство выполняется.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' = j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' = j &amp;lt; j' &amp;lt;/tex&amp;gt;. Тогда неравенство четырехугольника сводится к:&lt;br /&gt;
#: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; k = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \leqslant j &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant w[i][j] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} так как &amp;lt;tex&amp;gt; w[i][j'] \geqslant w[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \geqslant j &amp;lt;/tex&amp;gt; {{---}} аналогичный предыдущему случай.&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' &amp;lt; j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' &amp;lt; j &amp;lt; j' &amp;lt;/tex&amp;gt; &lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; y = R[i'][j] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; z = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \leqslant y &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: Получили &amp;lt;tex&amp;gt; i \leqslant z \leqslant y \leqslant j &amp;lt;/tex&amp;gt;. Запишем:&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i'][j'] + D[i][j] \leqslant D_y[i'][j'] + D_z[i][j] = w[i'][j'] + D[i'][y-1] + D[y][j'] + w[i][j] + D[i][z-1] + D[z][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[z][j] + D[y][j'] &amp;lt;/tex&amp;gt; {{---}} по неравенству четырехугольника для &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[y][j] + D[z][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] + D[i'][j] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \geqslant y &amp;lt;/tex&amp;gt; доказывается аналогично.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
| about=&lt;br /&gt;
Монотонность точки разреза&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \forall i \leqslant j : R[i][j] \leqslant R[i][j+1] \leqslant R[i+1][j+1] &amp;lt;/tex&amp;gt;.  &lt;br /&gt;
| proof=&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; i = j &amp;lt;/tex&amp;gt; неравенство, очевидно, выполняется. Рассматриваем случай &amp;lt;tex&amp;gt; i &amp;lt; j &amp;lt;/tex&amp;gt; и только случай &amp;lt;tex&amp;gt; R[i][j] \leqslant R[i][j+1] &amp;lt;/tex&amp;gt; (вторая часть доказывается аналогично):&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; {{---}} максимальный индекс, в котором достигается минимум, достаточно показать, что:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: [D_{k'}[i][j] \leqslant D_k[i][j]] \Rightarrow [D_{k'}[i][j+1] \leqslant D_k[i][j+1]] &amp;lt;/tex&amp;gt; {{---}} фактически, это означает что если на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt; разрез оптимальнее по &amp;lt;tex&amp;gt; k' &amp;lt;/tex&amp;gt;, чем по &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, то он также будет оптимальнее и на отрезке &amp;lt;tex&amp;gt; i..j+1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Докажем более сильное неравенство:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: D_k[i][j] - D_{k'}[i][j] \leqslant D_k[i][j+1] - D_{k'}[i][j+1] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D_k[i][j] + D_{k'}[i][j+1] \leqslant D_k[i][j+1] + D_{k'}[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][j] + D[i][k-1] + D[h][j]) + (w[i][j+1] + D[i][k'-1] + D[k][j+1]) \leqslant (w[i][j+1] + D[i][k-1] + D[k][j+1]) + (w[i][j] + D[i][k'-1] + D[k'][j]) &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D[k][j] + D[k'][j+1] \leqslant D[k][j+1] + D[k'][j] &amp;lt;/tex&amp;gt; {{---}} получили неравенство четырехугольника для &amp;lt;tex&amp;gt; k \leqslant k' \leqslant j \leqslant j+1 &amp;lt;/tex&amp;gt;, что является верным из предыдущей леммы. Теорема доказана.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Объяснение квадратичной асимптотики ==&lt;br /&gt;
Рассмотрим матрицу &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt;. Так как отрезки &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; i &amp;gt; j &amp;lt;/tex&amp;gt; мы не рассматриваем, она будет верхнетреугольной. Вначале она будет заполнена так, что &amp;lt;tex&amp;gt; R[i][i] = i &amp;lt;/tex&amp;gt; (так как для отрезка, состоящего из одного элемента, он же и является точкой разреза). Далее, для любого элемента &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; его значения лежат между &amp;lt;tex&amp;gt; R[i][j-1] &amp;lt;/tex&amp;gt; (левый элемент в матрице) и &amp;lt;tex&amp;gt; R[i+1][j] &amp;lt;/tex&amp;gt; (нижний элемент в матрице). Так как мы используем динамику по подотрезкам, то сначала мы рассчитаем &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; для отрезков длины 2, затем 3, и так далее до n. Фактически, мы будем обходить диагонали матрицы, количество которых равно n.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим элемент &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i][j-1] \leqslant R[i][j] \leqslant R[i+1][j] &amp;lt;/tex&amp;gt;. Следующий элемент, который мы будем пересчитывать {{---}} &amp;lt;tex&amp;gt; R[i+1][j+1] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i+1][j] \leqslant R[i+1][j+1] \leqslant R[i+2][j+1] &amp;lt;/tex&amp;gt;. Таким образом, заполняя одну диагональ, алгоритм сделает не более n шагов, а так как диагоналей n, получили асимптотику &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Источники информации ==&lt;br /&gt;
* [http://www.sciencedirect.com/science/article/pii/S0304397596003209 S.V. Nagaraj {{---}} Tutorial: Optimal binary search trees]&lt;br /&gt;
* ''Кнут Д.Э.'' {{---}} Искусство программирования, том 3. Сортировка и поиск. — М.: «Вильямс», 2005.&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;br /&gt;
[[Категория:Способы оптимизации методов динамического программирования]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D1%8B%D1%85_%D0%BF%D0%BE%D0%B4%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8F%D1%85,_%D1%82%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%BE_%D1%81%D0%B2%D1%8F%D0%B7%D0%B8_%D0%B4%D0%BB%D0%B8%D0%BD%D1%8B_%D0%9D%D0%92%D0%9F_%D0%B8_%D0%9D%D0%A3%D0%9F&amp;diff=58952</id>
		<title>Задача о монотонных подпоследовательностях, теорема о связи длины НВП и НУП</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D1%8B%D1%85_%D0%BF%D0%BE%D0%B4%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8F%D1%85,_%D1%82%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%BE_%D1%81%D0%B2%D1%8F%D0%B7%D0%B8_%D0%B4%D0%BB%D0%B8%D0%BD%D1%8B_%D0%9D%D0%92%D0%9F_%D0%B8_%D0%9D%D0%A3%D0%9F&amp;diff=58952"/>
				<updated>2017-01-06T17:10:34Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Исправил замечания&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Последовательность''' (англ. ''sequence'') {{---}} это набор элементов некоторого множества пронумерованный натуральными числами. Последовательность является результатом последовательного выбора элементов множества. При этом элементы последовательности могут повторяться. В частности, последовательность не является подмножеством заданного множества.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Виды последовательностей ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
Последовательность &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; элементов множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; называется '''''неубывающей''''' (англ. ''nondecreasing''), если каждый элемент этой последовательности не превосходит следующего за ним. &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; &amp;amp;mdash; '''''неубывающая''''' &amp;lt;tex&amp;gt;\Leftrightarrow\forall n \in \mathbb N: x_n \leqslant x_{n+1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
Последовательность &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; элементов множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; называется '''''невозрастающей''''' (англ. ''nonincreasing''), если каждый следующий элемент этой последовательности не превосходит предыдущего. &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; &amp;amp;mdash; '''''невозрастающая''''' &amp;lt;tex&amp;gt;\Leftrightarrow\forall n \in \mathbb N: x_n \geqslant x_{n+1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
Последовательность &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; элементов множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; называется '''''возрастающей''''' (англ. ''increasing''), если каждый следующий элемент этой последовательности превышает предыдущий. &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; &amp;amp;mdash; '''''возрастающая''''' &amp;lt;tex&amp;gt;\Leftrightarrow\forall n \in \mathbb N: x_n &amp;lt; x_{n+1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
Последовательность &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; элементов множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; называется '''''убывающей''''' (англ. ''decreasing''), если каждый элемент этой последовательности превышает следующий за ним. &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; &amp;amp;mdash; '''''убывающая''''' &amp;lt;tex&amp;gt;\Leftrightarrow\forall n \in \mathbb N: x_n &amp;gt; x_{n+1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
Последовательность называется '''монотонной''' (англ. ''monotonic''), если она является неубывающей, либо невозрастающей.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
Последовательность называется '''строго монотонной''' (англ. ''strictly monotonic''), если она является возрастающей, либо убывающей.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что строго монотонная последовательность является монотонной.&lt;br /&gt;
&lt;br /&gt;
== Теорема о связи длины НВП и НУП ==&lt;br /&gt;
&lt;br /&gt;
{{&lt;br /&gt;
Теорема&lt;br /&gt;
|author=&lt;br /&gt;
|about=&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; {{---}} перестановка чисел длины &amp;lt;tex&amp;gt;n, l&amp;lt;/tex&amp;gt; {{---}} длина наибольшей возрастающей подпоследовательности ([[Задача о наибольшей возрастающей подпоследовательности|НВП]]), &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; {{---}} длина наибольшей убывающей подпоследовательности (НУП). Тогда &amp;lt;tex&amp;gt;l k \geqslant n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим два массива длины &amp;lt;tex&amp;gt;n : S &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; T &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; S_i &amp;lt;/tex&amp;gt; {{---}} длина НВП, которая заканчивается на &amp;lt;tex&amp;gt;a_i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; T_i &amp;lt;/tex&amp;gt; {{---}} длина НУП, которая начинается на &amp;lt;tex&amp;gt;a_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Докажем, что все пары &amp;lt;tex&amp;gt;(S_i, T_i)&amp;lt;/tex&amp;gt; различны.&lt;br /&gt;
Пусть существуют такие &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; , что &amp;lt;tex&amp;gt; S_i &amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt; S_j &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; T_i &amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt; T_j&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;a_i &amp;lt; a_j&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a_j &amp;lt;/tex&amp;gt; можно добавить к НВП, заканчивающейся на &amp;lt;tex&amp;gt; a_i &amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;S_j \geqslant S_i + 1&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;a_i &amp;gt; a_j&amp;lt;/tex&amp;gt;, то по аналогии &amp;lt;tex&amp;gt;T_i \geqslant T_j + 1&amp;lt;/tex&amp;gt;. Противоречие! Следовательно все такие пары различны.&lt;br /&gt;
&lt;br /&gt;
Заметим что &amp;lt;tex&amp;gt;1 \leqslant S_i \leqslant l, 1 \leqslant T_i \leqslant k&amp;lt;/tex&amp;gt;, поэтому существуют &amp;lt;tex&amp;gt;l k&amp;lt;/tex&amp;gt; различных пар &amp;lt;tex&amp;gt; (S_i, T_i) &amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;l k &amp;lt; n&amp;lt;/tex&amp;gt; тогда среди &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; пар найдутся две одинаковые. Такого быть не может по доказанному выше, т. е. &amp;lt;tex&amp;gt;l k \geqslant n&amp;lt;/tex&amp;gt;, ч. т. д.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Следствие из теоремы ==&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина последовательности, тогда длина наибольшей монотонной подпоследовательности не меньше &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C#.D0.9D.D0.B5.D0.BA.D0.BE.D1.82.D0.BE.D1.80.D1.8B.D0.B5_.D0.B2.D0.B8.D0.B4.D1.8B_.D0.BF.D0.BE.D1.81.D0.BB.D0.B5.D0.B4.D0.BE.D0.B2.D0.B0.D1.82.D0.B5.D0.BB.D1.8C.D0.BD.D0.BE.D1.81.D1.82.D0.B5.D0.B9 Википедия {{---}} Последовательность]&lt;br /&gt;
&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Longest_increasing_subsequence Wikipedia {{---}} Longest increasing subsequence]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Комбинаторика]]&lt;br /&gt;
[[Категория: Свойства комбинаторных объектов]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%9D%D0%A4&amp;diff=58946</id>
		<title>ДНФ</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%9D%D0%A4&amp;diff=58946"/>
				<updated>2017-01-06T16:43:46Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Исправил замечания&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== ДНФ ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Простой конъюнкцией''' (англ. ''inclusive conjunction'') или '''конъюнктом''' (англ. ''conjunct'') называется конъюнкция одной или нескольких переменных или их отрицаний, причём каждая переменная встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
Простая конъюнкция&lt;br /&gt;
* '''полная''', если в неё каждая переменная (или её отрицание) входит ровно &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt; раз;&lt;br /&gt;
* '''монотонная''', если она не содержит отрицаний переменных.&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Дизъюнктивная нормальная форма, ДНФ''' (англ. ''disjunctive normal form, DNF'') {{---}} нормальная форма, в которой [[Определение булевой функции|булева функция]] имеет вид дизъюнкции нескольких простых конъюнктов.&lt;br /&gt;
}}&lt;br /&gt;
Пример ДНФ:&lt;br /&gt;
&amp;lt;tex&amp;gt;f(x,y,z) = (x \land y) \lor (y \land \neg {z})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== СДНФ ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Совершенная дизъюнктивная нормальная форма, СДНФ''' (англ. ''perfect disjunctive normal form, PDNF'') — это ДНФ, удовлетворяющая условиям:&lt;br /&gt;
* в ней нет одинаковых простых конъюнкций,&lt;br /&gt;
* каждая простая конъюнкция полная.&lt;br /&gt;
}}&lt;br /&gt;
Пример СДНФ:&lt;br /&gt;
&amp;lt;tex&amp;gt;f(x,y,z) = (x \land \neg {y} \land z) \lor (x \land y \land \neg {z})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Для любой булевой функции &amp;lt;tex&amp;gt;f(\vec {x})&amp;lt;/tex&amp;gt;, не равной тождественному нулю, существует СДНФ, ее задающая.&lt;br /&gt;
|proof = &lt;br /&gt;
Для любой булевой функции выполняется следующее соотношение, называемое '''разложением Шеннона''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f(\vec{x}) = \neg  x_i \wedge f(x_1, \dots ,x_{i-1},0,x_{i+1}, \dots ,x_n) \vee&lt;br /&gt;
x_i \wedge f(x_1, \dots ,x_{i-1},1,x_{i+1}, \dots ,x_n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Данное соотношение легко проверить подстановкой возможных значений &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). Эта формула позволяет выносить &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; за знак функции. Последовательно вынося &amp;lt;tex&amp;gt;x_1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;x_2&amp;lt;/tex&amp;gt;,.., &amp;lt;tex&amp;gt;x_n&amp;lt;/tex&amp;gt; за знак &amp;lt;tex&amp;gt;f(\vec{x})&amp;lt;/tex&amp;gt;, получаем следующую формулу: &lt;br /&gt;
&amp;lt;tex&amp;gt; f(\vec{x}) = \neg  x_1 \wedge \neg  x_2 \wedge ...\wedge \neg  x_{n-1} \wedge \neg  x_n \wedge f(0,0,...,0,0)~\vee~&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\neg  x_1 \wedge \neg  x_2 \wedge ... \wedge \neg  x_{n-1} \wedge x_n \wedge f(0,0,...,0,1) ~\vee~ \\&lt;br /&gt;
\dots \\&lt;br /&gt;
~\vee~ x_1 \wedge x_2 \wedge ... \wedge x_{n-1} \wedge \neg  x_n \wedge f(1,1,...,1,0) ~\vee~\\ &lt;br /&gt;
x_1 \wedge x_2 \wedge ... \wedge x_{n-1} \wedge x_n \wedge f(1,1,...,1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как применение данного соотношения к каждой из переменных увеличивает количество конъюнктов в два раза, то для функции от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных мы имеем &amp;lt;tex&amp;gt;2^n&amp;lt;/tex&amp;gt; конъюнктов. Каждый из них соответствует значению функции на одном из &amp;lt;tex&amp;gt;2^n&amp;lt;/tex&amp;gt; возможных наборов значений &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; переменных. Если на некотором наборе &amp;lt;tex&amp;gt;f(\vec{x})=0&amp;lt;/tex&amp;gt;, то весь соответствующий конъюнкт также равен нулю и из представления данной функции его можно исключить. Если же &amp;lt;tex&amp;gt; f(\vec{x})=1&amp;lt;/tex&amp;gt;, то в соответствующем конъюнкте само значение функции можно опустить. В результате для произвольной функции была построена СДНФ.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм построения СДНФ по таблице истинности ==&lt;br /&gt;
# В таблице истинности отмечаем те наборы переменных, на которых значение функции равно &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждого отмеченного набора записываем конъюнкцию всех переменных по следующему правилу: если значение некоторой переменной есть &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;, то в конъюнкцию включаем саму переменную, иначе ее отрицание.&lt;br /&gt;
# Все полученные конъюнкции связываем операциями дизъюнкции.&lt;br /&gt;
&lt;br /&gt;
== Пример построения СДНФ для медианы==&lt;br /&gt;
1. В таблице истинности отмечаем те наборы переменных, на которых значение функции равно &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:10cm&amp;quot; border=1&lt;br /&gt;
|+&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#EEEEFF&lt;br /&gt;
|&amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt; y &amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt; z &amp;lt;/tex&amp;gt;|| &amp;lt;tex&amp;gt; \langle x,y,z \rangle &amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 0 || 0 || 0&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 0 || 1 || 0&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 1 || 0 || 0&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 0 || 1 || 1 || 1&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 1 || 0 || 0 || 0&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 0 || 1 || 1&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 1 || 0 || 1&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
2. Для каждого отмеченного набора записываем конъюнкцию всех переменных по следующему правилу: если значение некоторой переменной есть &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;, то в конъюнкцию включаем саму переменную, иначе ее отрицание.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;width:16cm&amp;quot; border=1&lt;br /&gt;
|+&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#EEEEFF&lt;br /&gt;
|&amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt; y &amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt; z &amp;lt;/tex&amp;gt;|| &amp;lt;tex&amp;gt; \langle x,y,z \rangle &amp;lt;/tex&amp;gt; || &lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 0 || 0 || 0 ||&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 0 || 1 || 0 ||&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 1 || 0 || 0 ||&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 0 || 1 || 1 || 1 || &amp;lt;tex&amp;gt;(\neg {x} \land y \land z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 1 || 0 || 0 || 0 ||&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 0 || 1 || 1 || &amp;lt;tex&amp;gt;(x \land \neg {y} \land z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 1 || 0 || 1 || &amp;lt;tex&amp;gt;(x \land y \land \neg {z})&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 1 || 1 || 1 || &amp;lt;tex&amp;gt;(x \land y \land z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
3. Все полученные конъюнкции связываем операциями дизъюнкции:&lt;br /&gt;
                                                                  &lt;br /&gt;
&amp;lt;tex&amp;gt; \langle x,y,z \rangle = (x \land y \land z) \lor (\neg {x} \land y \land z) \lor (x \land \neg {y} \land z) \lor (x \land y \land \neg {z})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Примеры СДНФ для некоторых функций==&lt;br /&gt;
Стрелка Пирса: &amp;lt;tex&amp;gt; x \downarrow y = (\neg {x} \land \neg {y})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Исключающее или: &amp;lt;tex&amp;gt; x \oplus y \oplus z = (\overline{x} \land \overline{y} \land z) \lor (\overline{x} \land y \land \overline{z}) \lor (x \land \overline{y} \land \overline{z}) \lor (x \land y \land z)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== См. также ==&lt;br /&gt;
&lt;br /&gt;
* [[Сокращенная и минимальная ДНФ]]&lt;br /&gt;
* [[КНФ]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации ==&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%A1%D0%94%D0%9D%D0%A4 СДНФ — Википедия]&lt;br /&gt;
* [http://dvo.sut.ru/libr/himath/w163rabk/index.htm Е.Л Рабкин,  Ю.Б. Фарфоровская — Дискретная математика]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Булевы функции ]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=58880</id>
		<title>Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=58880"/>
				<updated>2017-01-05T21:23:55Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Исправил битую ссылку&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Определение ==&lt;br /&gt;
{{Определение &lt;br /&gt;
| definition =&lt;br /&gt;
[[Оптимальный префиксный код с длиной кодового слова не более L бит|Оптимальный префиксный код]] с сохранением порядка (англ. ''order-preserving code'', ''alphabetic code'').&lt;br /&gt;
 &lt;br /&gt;
Пусть у нас есть алфавит &amp;lt;tex&amp;gt; \Sigma &amp;lt;/tex&amp;gt;. Каждому символу &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; сопоставим его код &amp;lt;tex&amp;gt; p_i &amp;lt;/tex&amp;gt;. Кодирование называется оптимальным префиксным с сохранением порядка (алфавитным), если соблюдаются:&lt;br /&gt;
# Условие порядка {{---}} &amp;lt;tex&amp;gt; \forall i, j : c_i &amp;lt; c_j \iff p_i &amp;lt; p_j &amp;lt;/tex&amp;gt;. То есть, если символ &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; лексикографически меньше символа &amp;lt;tex&amp;gt; c_j &amp;lt;/tex&amp;gt;, его код также будет [[лексикографический порядок | лексикографически]] меньше, и наоборот.&lt;br /&gt;
# Условие оптимальности {{---}} &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^{|\Sigma|} f_i \cdot |p_i| &amp;lt;/tex&amp;gt; {{---}} минимально, где &amp;lt;tex&amp;gt; f_i &amp;lt;/tex&amp;gt; {{---}} частота встречаемости символа &amp;lt;tex&amp;gt; c_i &amp;lt;/tex&amp;gt; в тексте, а &amp;lt;tex&amp;gt; |p_i| &amp;lt;/tex&amp;gt; {{---}} длина его кода.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Решим задачу, используя ДП на подотрезках. Пусть в ячейке &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; хранится минимальная стоимость кодового дерева для отрезка алфавита от &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда пересчет &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; будет происходить так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D[i][j] = \min\limits_{k = i}^{j - 1} \left ( D[i][k] + D[k + 1][j] \right ) + w[i][j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Базой динамики будет &amp;lt;tex&amp;gt; D[i][i] = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Добавочный член &amp;lt;tex&amp;gt;w[i][j] = \sum\limits_{t = i}^{j} f_t &amp;lt;/tex&amp;gt; возникает от того что каждым объединением двух подотрезков мы увеличиваем высоту дерева на 1, а значит, и длины всех кодов символов &amp;lt;tex&amp;gt; c_i .. c_j &amp;lt;/tex&amp;gt; также увеличиваются на 1.&lt;br /&gt;
&lt;br /&gt;
Тогда такое ''наибольшее'' &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, на котором достигается этот минимум, называется точкой разреза для отрезка &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;. Пусть в ячейке &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; хранится точка разреза на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если разрез происходит по какому-то определенному индексу &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; , такой разрез обозначим &amp;lt;tex&amp;gt; D_q[i][j] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, получили алгоритм, работающий за &amp;lt;tex&amp;gt; O(n^3) &amp;lt;/tex&amp;gt;. Коды каждого символа можно легко получить так же, как в алгоритме Хаффмана {{---}} обходом по построенному дереву.&lt;br /&gt;
&lt;br /&gt;
Если доказать монотонность точки разреза, то можно уменьшить асимптотику алгоритма до &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Монотонность точки разреза ==&lt;br /&gt;
Для доказательства этого сперва докажем несколько лемм.&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
| definition=&lt;br /&gt;
Функция &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; удовлетворяет '''неравенству четырехугольника''' (англ. ''quadrangle inequation''), если&lt;br /&gt;
: &amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : a[i][j] + a[i'][j'] \leqslant a[i'][j] + a[i][j']&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
&amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника.&lt;br /&gt;
| proof=&lt;br /&gt;
Заметим, что &amp;lt;tex&amp;gt; w[i][j] = w[i][t] + w[t+1][j] &amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt; w[i][j] &amp;lt;/tex&amp;gt; {{---}} простая арифметическая сумма. Тогда:&lt;br /&gt;
: &amp;lt;tex&amp;gt; w[i][j] + w[i'][j'] \leqslant w[i'][j] + w[i][j']&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][i' - 1] + w[i'][j]) + (w[i'][j] + w[j + 1][j']) \leqslant (w[i'][j]) + (w[i][i' - 1] + w[i'][j] + w[j + 1][j']) &amp;lt;/tex&amp;gt;&lt;br /&gt;
Получили &amp;lt;tex&amp;gt; 0 \leqslant 0 &amp;lt;/tex&amp;gt;, что является верным. Лемма доказана.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt; также удовлетворяет неравенству четырехугольника, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : D[i][j] + D[i'][j'] \leqslant D[i'][j] + D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
| proof=&lt;br /&gt;
При &amp;lt;tex&amp;gt; i = i' &amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt; j = j' &amp;lt;/tex&amp;gt;, очевидно, неравенство выполняется.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' = j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' = j &amp;lt; j' &amp;lt;/tex&amp;gt;. Тогда неравенство четырехугольника сводится к:&lt;br /&gt;
#: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; k = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \leqslant j &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant w[i][j] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} так как &amp;lt;tex&amp;gt; w[i][j'] \geqslant w[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \geqslant j &amp;lt;/tex&amp;gt; {{---}} аналогичный предыдущему случай.&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' &amp;lt; j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' &amp;lt; j &amp;lt; j' &amp;lt;/tex&amp;gt; &lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; y = R[i'][j] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; z = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \leqslant y &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: Получили &amp;lt;tex&amp;gt; i \leqslant z \leqslant y \leqslant j &amp;lt;/tex&amp;gt;. Запишем:&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i'][j'] + D[i][j] \leqslant D_y[i'][j'] + D_z[i][j] = w[i'][j'] + D[i'][y-1] + D[y][j'] + w[i][j] + D[i][z-1] + D[z][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[z][j] + D[y][j'] &amp;lt;/tex&amp;gt; {{---}} по неравенству четырехугольника для &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[y][j] + D[z][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] + D[i'][j] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \geqslant y &amp;lt;/tex&amp;gt; доказывается аналогично.&lt;br /&gt;
Лемма доказана.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
| about=&lt;br /&gt;
Монотонность точки разреза&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \forall i \leqslant j : R[i][j] \leqslant R[i][j+1] \leqslant R[i+1][j+1] &amp;lt;/tex&amp;gt;  &lt;br /&gt;
| proof=&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; i = j &amp;lt;/tex&amp;gt; неравенство, очевидно, выполняется. Рассматриваем случай &amp;lt;tex&amp;gt; i &amp;lt; j &amp;lt;/tex&amp;gt; и только случай &amp;lt;tex&amp;gt; R[i][j] \leqslant R[i][j+1] &amp;lt;/tex&amp;gt;(вторая часть доказывается аналогично):&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; {{---}} максимальный индекс, в котором достигается минимум, достаточно показать, что:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: [D_{k'}[i][j] \leqslant D_k[i][j]] \Rightarrow [D_{k'}[i][j+1] \leqslant D_k[i][j+1]] &amp;lt;/tex&amp;gt; {{---}} фактически, это означает что если на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt; разрез оптимальнее по &amp;lt;tex&amp;gt; k' &amp;lt;/tex&amp;gt;, чем по &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, то он также будет оптимальнее и на отрезке &amp;lt;tex&amp;gt; i..j+1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Докажем более сильное неравенство:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: D_k[i][j] - D_{k'}[i][j] \leqslant D_k[i][j+1] - D_{k'}[i][j+1] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D_k[i][j] + D_{k'}[i][j+1] \leqslant D_k[i][j+1] + D_{k'}[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][j] + D[i][k-1] + D[h][j]) + (w[i][j+1] + D[i][k'-1] + D[k][j+1]) \leqslant (w[i][j+1] + D[i][k-1] + D[k][j+1]) + (w[i][j] + D[i][k'-1] + D[k'][j]) &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D[k][j] + D[k'][j+1] \leqslant D[k][j+1] + D[k'][j] &amp;lt;/tex&amp;gt; {{---}} получили неравенство четырехугольника для &amp;lt;tex&amp;gt; k \leqslant k' \leqslant j \leqslant j+1 &amp;lt;/tex&amp;gt;, что является верным из предыдущей леммы. Теорема доказана.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Объяснение квадратичной асимптотики ==&lt;br /&gt;
Рассмотрим матрицу &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt;. Так как отрезки &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; i &amp;gt; j &amp;lt;/tex&amp;gt; мы не рассматриваем, она будет верхнетреугольной. Вначале она будет заполнена так, что &amp;lt;tex&amp;gt; R[i][i] = i &amp;lt;/tex&amp;gt;(так как для отрезка, состоящего из одного элемента, он же и является точкой разреза). Далее, для любого элемента &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; его значения лежат между &amp;lt;tex&amp;gt; R[i][j-1] &amp;lt;/tex&amp;gt; (левый элемент в матрице) и &amp;lt;tex&amp;gt; R[i+1][j] &amp;lt;/tex&amp;gt; (нижний элемент в матрице). Так как мы используем динамику по подотрезкам, то сначала мы рассчитаем &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; для отрезков длины 2, затем 3, и так далее до n. Фактически, мы будем обходить диагонали матрицы, количество которых равно n.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим элемент &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i][j-1] \leqslant R[i][j] \leqslant R[i+1][j] &amp;lt;/tex&amp;gt;. Следующий элемент, который мы будем пересчитывать {{---}} &amp;lt;tex&amp;gt; R[i+1][j+1] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i+1][j] \leqslant R[i+1][j+1] \leqslant R[i+2][j+1] &amp;lt;/tex&amp;gt;. Таким образом, заполняя одну диагональ, алгоритм сделает не более n шагов, а так как диагоналей n, получили асимптотику &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Источники информации ==&lt;br /&gt;
[http://www.sciencedirect.com/science/article/pii/S0304397596003209 S.V. Nagaraj {{---}} Tutorial: Optimal binary search trees]&lt;br /&gt;
&lt;br /&gt;
''Кнут Д.Э.'' {{---}} Искусство программирования, том 3. Сортировка и поиск. — М.: «Вильямс», 2005.&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58876</id>
		<title>Задача о наибольшей общей возрастающей последовательности</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58876"/>
				<updated>2017-01-05T21:15:21Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Отформатировал псевдокод; заменил дефисы на тире; не нашёл терминов, нуждающихся в английском эквиваленте&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон: Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Даны два массива: &amp;lt;tex&amp;gt; a[1..n] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..m] &amp;lt;/tex&amp;gt;. Требуется найти их ''наибольшую общую возрастающую подпоследовательность (НОВП).''}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
'''Наибольшая общая возрастающая подпоследовательность, НОВП''' (англ. ''longest common increasing subsequence, LCIS'')  массива &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; и массива &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; — это последовательность &amp;lt;tex&amp;gt; X = \left \langle x_1, x_2, ..., x_k \right \rangle &amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt; x_1 &amp;lt; x_2 &amp;lt; \dots &amp;lt; x_k &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; X &amp;lt;/tex&amp;gt; является ''подпоследовательностью'' &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;4&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Построим следующую динамику: &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это длина наибольшей возрастающей подпоследовательности массивов &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, последний элемент которой &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] (a[i] = b[j]) &amp;lt;/tex&amp;gt;. Будем заполнять &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, а при равенстве по увеличению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Ответом на задачу будет максимум из всех элементов &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; (где &amp;lt;tex&amp;gt; i = 1...n &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; j = 1...m. &amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Заполнять &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; будем следующим образом: на очередном шаге сравниваем элементы &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt; d[i][j] = 0 &amp;lt;/tex&amp;gt; (так как нет НОВП, оканчивающейся в разных элементах).&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то эти элементы могут быть частью НОВП. Переберём, какие элементы стояли перед ними в массивах &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;. Заметим, что предыдущие значения &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; уже известны, тогда очередное значение &amp;lt;tex dpi=&amp;quot;130&amp;quot;&amp;gt; d[i][j] = \max\limits_{k = 1..i-1 \atop l = 1..j-1} d[k][l] + 1 &amp;lt;/tex&amp;gt; при условии, что &amp;lt;tex&amp;gt; a[k] = b[l]. &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Длина НОВП будет в элементе с максимальным значением &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt;. Для восстановления подпоследовательности можно хранить массив предков &amp;lt;tex&amp;gt; prev[1..n] &amp;lt;/tex&amp;gt; массива &amp;lt;tex&amp;gt; a: prev[i] &amp;lt;/tex&amp;gt; {{---}} индекс предыдущего элемента НОВП, которая оканчивается в &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 int[] '''LCIS'''(a: int[], b: int[])&lt;br /&gt;
   '''for''' i = 1 '''to''' n &lt;br /&gt;
     '''for''' j = 1 '''to''' m&lt;br /&gt;
       '''if''' a[i] == b[j]&lt;br /&gt;
         d[i][j] = 1 &amp;lt;font color=green&amp;gt; // НОВП как минимум 1, состоит из одного элемента a[i] &amp;lt;-&amp;gt; b[j] &amp;lt;/font&amp;gt;&lt;br /&gt;
           '''for''' k = 1 '''to''' i - 1&lt;br /&gt;
             '''for''' l = 1 '''to''' j - 1&lt;br /&gt;
               '''if''' a[k] == b[l] '''and''' a[k] &amp;lt; a[i] '''and''' d[i][j] &amp;lt; d[k][l] + 1&lt;br /&gt;
                 d[i][j] = d[k][l] + 1&lt;br /&gt;
                 prev[i] = k&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление&amp;lt;/font&amp;gt;&lt;br /&gt;
   b_i = 1&lt;br /&gt;
   b_j = 1&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     '''for''' j = 1 '''to''' m &lt;br /&gt;
       '''if''' d[b_i][b_j] &amp;lt; d[i][j]&lt;br /&gt;
         b_i = i&lt;br /&gt;
         b_j = j&lt;br /&gt;
   pos = b_i &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву a, выписывая элементы НОВП&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(a[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Улучшим предыдущее решение. Пусть теперь &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} динамика, в которой элемент &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; по-прежнему последний представитель НОВП массива &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; может не быть быть последним представителем массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, будем &amp;quot;протаскивать&amp;quot; последнее удачное сравнение в динамике: &amp;lt;tex&amp;gt; d[i][j] = d[i][j-1] &amp;lt;/tex&amp;gt; (понять это можно так: &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt; , поэтому &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; не последний представитель НОВП из массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, а значит предыдущий элемент НОВП находится в префиксе &amp;lt;tex&amp;gt; b[1..j-1] &amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt; d[i][j-1] &amp;lt;/tex&amp;gt; уже посчитан).&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то одним дополнительным циклом пробежим по &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и найдём предыдущий элемент НОВП, оканчивающейся в &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; (он меньше &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt;). Из подходящих элементов выберем тот, для которого &amp;lt;tex&amp;gt; d[k][j] &amp;lt;/tex&amp;gt; {{---}} максимальна.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi=&amp;quot;120&amp;quot;&amp;gt; d[i][j] = \max\limits_{k = 1..i-1} d[k][j] + 1 &amp;lt;/tex&amp;gt; при условии, что &amp;lt;tex&amp;gt; a[k] &amp;lt; a[i].&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Длина НОВП будет в элементе с максимальным значением &amp;lt;tex&amp;gt; d[i][m] &amp;lt;/tex&amp;gt;. Для восстановления ответа будем хранить массив предков по массиву &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;, как и в предыдущем решении.&lt;br /&gt;
&lt;br /&gt;
 int[] '''LCIS'''(a: int[], b: int[])&lt;br /&gt;
   '''for''' i = 1 '''to''' n &lt;br /&gt;
     '''for''' j = 1 '''to''' m&lt;br /&gt;
       '''if''' a[i] == b[j]&lt;br /&gt;
         d[i][j] = 1 &amp;lt;font color=green&amp;gt;// НОВП как минимум 1, состоит из одного элемента a[i] &amp;lt;-&amp;gt; b[j]&amp;lt;/font&amp;gt;&lt;br /&gt;
         '''for''' k = 1 '''to''' i - 1&lt;br /&gt;
           '''if''' a[k] &amp;lt; a[i] '''and''' d[i][j] &amp;lt; d[k][j] + 1&lt;br /&gt;
             d[i][j] = d[k][j] + 1&lt;br /&gt;
             prev[i] = k&lt;br /&gt;
       '''else'''&lt;br /&gt;
         d[i][j] = d[i][j - 1] &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление&amp;lt;/font&amp;gt;&lt;br /&gt;
   pos = 1 &amp;lt;font color=green&amp;gt;// ищем элемент c максимальным d[pos][m]&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     '''if''' d[pos][m] &amp;lt; d[i][m]&lt;br /&gt;
       pos = i&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву a, выписывая элементы НОВП&amp;lt;/font&amp;gt; &lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(a[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Модифицируем предыдущее решение, добавив небольшую &amp;quot;хитрость&amp;quot;. Теперь &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это длина наибольшей общей возрастающей подпоследовательности префиксов &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;, причем элемент &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последний представитель НОВП массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; может не быть последним в массиве &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;. Вычислять &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; будем всё так же: сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, а при равенстве {{---}} по увеличению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Тогда для очередного значения &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; есть два варианта:&lt;br /&gt;
*&amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; не входит в НОВП. Тогда &amp;lt;tex&amp;gt; d[i][j] = d[i-1][j] &amp;lt;/tex&amp;gt;: значение динамики уже посчитано на префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
*&amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; входит в НОВП. Это значит, что &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то есть для подсчёта &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; нужно пробегать циклом по &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt; в поисках элемента &amp;lt;tex&amp;gt; b[k] &amp;lt; b[j] &amp;lt;/tex&amp;gt; с наибольшим значением &amp;lt;tex&amp;gt; d[i-1][k] &amp;lt;/tex&amp;gt;. Но мы считаем &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, поэтому будем считать &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; ''фиксированным''. Чтобы не запускать цикл при каждом равенстве &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; элементу &amp;lt;tex&amp;gt; b[k] &amp;lt;/tex&amp;gt;, в дополнительной переменной &amp;lt;tex&amp;gt; best &amp;lt;/tex&amp;gt; будем хранить &amp;quot;лучший&amp;quot; элемент (и его индекс &amp;lt;tex&amp;gt; ind &amp;lt;/tex&amp;gt; в массиве &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;) такой, что этот элемент строго меньше &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; (а также меньше &amp;lt;tex&amp;gt; b[k] &amp;lt;/tex&amp;gt;) и значение динамики для него максимально: &amp;lt;tex&amp;gt; b[ind] &amp;lt; a[i] = b[k] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; best = d[i-1][ind] \rightarrow max. &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int[] '''LCIS'''(a: int[], b: int[])&lt;br /&gt;
   '''for''' i = 1 '''to''' n&lt;br /&gt;
     ind = 0 &amp;lt;font color=green&amp;gt;// позиция &amp;quot;лучшего&amp;quot; элемента в массиве b&amp;lt;/font&amp;gt;&lt;br /&gt;
     best = 0 &amp;lt;font color=green&amp;gt;// значение динамики для &amp;quot;лучшего&amp;quot; элемента&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' j = 1 '''to''' m	&lt;br /&gt;
       d[i][j] = d[i - 1][j] &amp;lt;font color=green&amp;gt;// НОВП на a[1..i - 1] и b[1..j] (без элемента a[i])&amp;lt;/font&amp;gt;&lt;br /&gt;
       '''if''' a[i] == b[j] '''and''' d[i - 1][j] &amp;lt; best + 1 &amp;lt;font color=green&amp;gt;// используем a[i]-й элемент для увеличения НОВП&amp;lt;/font&amp;gt;&lt;br /&gt;
         d[i][j] = best + 1                         &lt;br /&gt;
         prev[j] = ind                            &lt;br /&gt;
       '''if''' a[i] &amp;gt; b[j] '''and''' d[i - 1][j] &amp;gt; best &amp;lt;font color=green&amp;gt;// при следующем равенстве a[i] == b[j']&amp;lt;/font&amp;gt;&lt;br /&gt;
         best = d[i - 1][j] &amp;lt;font color=green&amp;gt;// в best будет храниться &amp;quot;лучший&amp;quot; элемент&amp;lt;/font&amp;gt;         &lt;br /&gt;
         ind = j &amp;lt;font color=green&amp;gt;// b[ind] &amp;lt; b[j'] и d[i][ind] &amp;lt;tex&amp;gt; \rightarrow &amp;lt;/tex&amp;gt; max&amp;lt;/font&amp;gt; &lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// восстановление (по массиву b)&amp;lt;/font&amp;gt;&lt;br /&gt;
   pos = 1 &amp;lt;font color=green&amp;gt;// ищем лучший элемент d[n][pos] &amp;lt;tex&amp;gt; \rightarrow &amp;lt;/tex&amp;gt; max&amp;lt;/font&amp;gt; &lt;br /&gt;
   '''for''' j = 1 '''to''' m&lt;br /&gt;
     '''if''' d[n][pos] &amp;lt; d[n][j]&lt;br /&gt;
       pos = j&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// проходим по массиву b, выписывая элементы НОВП&amp;lt;/font&amp;gt; &lt;br /&gt;
   '''while''' pos &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 0&lt;br /&gt;
     answer.pushBack(b[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
=== Доказательство оптимальности ===&lt;br /&gt;
В данной задаче используется принцип оптимальности на префиксе. Использование дополнительной переменной для подсчета всех случаев &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt; не влияет на корректность алгоритма {{---}} это всего лишь уловки реализации. Поэтому покажем, что для вычисления очередного значения &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; мы используем оптимальность на подзадачах и обращаемся к уже посчитанным значениям. &lt;br /&gt;
Напомним, как обозначается динамика: &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; {{---}} это НОВП на префиксах &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;, где последним элементом НОВП является элемент &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; может не быть равен &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; (то есть элемент &amp;lt;tex&amp;gt; a[i'] = b[j] &amp;lt;/tex&amp;gt; лежит где-то в префиксе &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt;). Итак, для &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; есть два варианта:&lt;br /&gt;
* &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; не влияет на результат, и последний элемент НОВП &amp;lt;tex&amp;gt; a[i'] = b[j] &amp;lt;/tex&amp;gt;  лежит в &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последние элементы НОВП префиксов &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} по определению динамики, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; как элемент, который может стать последним, не ухудшая результат. Действительно, последовательность строго возрастает, поэтому если в префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; есть элемент &amp;lt;tex&amp;gt; a[k] = b[j] &amp;lt;/tex&amp;gt;, то его можно заменить на элемент &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; без уменьшения длины НОВП. Если же в &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; такого элемента нет, то &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; {{---}} единственный из возможных вариантов. Итак, &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; {{---}} последние элементы НОВП. Значит, начало НОВП (&amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt;) лежит в префиксах &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j-1] &amp;lt;/tex&amp;gt; (значения для которых уже посчитаны). Мы ищем элемент &amp;lt;tex&amp;gt; b[k] &amp;lt; b[j] &amp;lt;/tex&amp;gt; с лучшей динамикой &amp;lt;tex&amp;gt; d[i-1][k] &amp;lt;/tex&amp;gt;, что удовлетворяет условию возрастания последовательности и автоматически гарантирует, что конец такой НОВП лежит в префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
&lt;br /&gt;
*[[Задача о наибольшей общей подпоследовательности]]&lt;br /&gt;
*[[Задача о наибольшей возрастающей подпоследовательности]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
[http://codeforces.ru/contest/10/problem/D Codeforces {{---}} Задача о наибольшей общей возрастающей подпоследовательности]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58855</id>
		<title>Задача о наибольшей общей возрастающей последовательности</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%B2%D0%BE%D0%B7%D1%80%D0%B0%D1%81%D1%82%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=58855"/>
				<updated>2017-01-05T19:36:15Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Добавил шаблон &amp;quot;задача&amp;quot;; правильно оформил источники информации&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон: Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Даны два массива: &amp;lt;tex&amp;gt; a[1..n] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..m] &amp;lt;/tex&amp;gt;. Требуется найти их ''наибольшую общую возрастающую подпоследовательность (НОВП).''}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
'''Наибольшая общая возрастающая подпоследовательность, НОВП''' (англ. ''longest common increasing subsequence, LCIS'')  массива &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; и массива &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; — это последовательность &amp;lt;tex&amp;gt; X = \left \langle x_1, x_2, ..., x_k \right \rangle &amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt; x_1 &amp;lt; x_2 &amp;lt; \dots &amp;lt; x_k &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; X &amp;lt;/tex&amp;gt; является ''подпоследовательностью'' &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;4&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Построим следующую динамику: &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; - это длина наибольшей возрастающей подпоследовательности массивов &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, последний элемент которой &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] (a[i] = b[j]) &amp;lt;/tex&amp;gt;. Будем заполнять &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, а при равенстве по увеличению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Ответом на задачу будет максимум из всех элементов &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; (где &amp;lt;tex&amp;gt; i = 1...n &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; j = 1...m. &amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Заполнять &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; будем следующим образом: на очередном шаге сравниваем элементы &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt; d[i][j] = 0 &amp;lt;/tex&amp;gt; (так как нет НОВП, оканчивающейся в разных элементах).&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то эти элементы могут быть частью НОВП. Переберём, какие элементы стояли перед ними в массивах &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;. Заметим, что предыдущие значения &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; уже известны, тогда очередное значение &amp;lt;tex dpi=&amp;quot;130&amp;quot;&amp;gt; d[i][j] = \max\limits_{k = 1..i-1 \atop l = 1..j-1} d[k][l] + 1 &amp;lt;/tex&amp;gt; при условии, что &amp;lt;tex&amp;gt; a[k] = b[l]. &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Длина НОВП будет в элементе с максимальным значением &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt;. Для восстановления подпоследовательности можно хранить массив предков &amp;lt;tex&amp;gt; prev[1..n] &amp;lt;/tex&amp;gt; массива &amp;lt;tex&amp;gt; a: prev[i] &amp;lt;/tex&amp;gt; - индекс предыдущего элемента НОВП, которая оканчивается в &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;int&amp;gt; '''LCIS'''(vector&amp;lt;int&amp;gt; a, vector&amp;lt;int&amp;gt; b)&lt;br /&gt;
   d = int[n][m]&lt;br /&gt;
   prev = int[n]&lt;br /&gt;
   '''for''' i = 1...n &lt;br /&gt;
     '''for''' j = 1...m&lt;br /&gt;
       '''if''' a[i] == b[j]&lt;br /&gt;
         d[i][j] = 1 // НОВП как минимум 1, состоит из одного элемента a[i] &amp;lt;-&amp;gt; b[j]&lt;br /&gt;
           '''for''' k = 1...i-1&lt;br /&gt;
             '''for''' l = 1...j-1&lt;br /&gt;
               '''if''' a[k] == b[l] '''and''' a[k] &amp;lt; a[i] '''and''' d[i][j] &amp;lt; d[k][l] + 1&lt;br /&gt;
                 d[i][j] = d[k][l] + 1&lt;br /&gt;
                 prev[i] = k&lt;br /&gt;
   //восстановление&lt;br /&gt;
   b_i = 1&lt;br /&gt;
   b_j = 1&lt;br /&gt;
   '''for''' i = 1...n&lt;br /&gt;
     '''for''' j = 1...m &lt;br /&gt;
       '''if''' d[b_i][b_j] &amp;lt; d[i][j]&lt;br /&gt;
         b_i = i&lt;br /&gt;
         b_j = j&lt;br /&gt;
   vector&amp;lt;int&amp;gt; answer&lt;br /&gt;
   pos = b_i        // проходим по массиву a, выписывая элементы НОВП&lt;br /&gt;
   '''while''' pos != 0&lt;br /&gt;
     answer.push(a[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Улучшим предыдущее решение. Пусть теперь &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; - динамика, в которой элемент &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; по-прежнему последний представитель НОВП массива &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; может не быть быть последним представителем массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, будем &amp;quot;протаскивать&amp;quot; последнее удачное сравнение в динамике: &amp;lt;tex&amp;gt; d[i][j] = d[i][j-1] &amp;lt;/tex&amp;gt; (понять это можно так: &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt; , поэтому &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; не последний представитель НОВП из массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, а значит предыдущий элемент НОВП находится в префиксе &amp;lt;tex&amp;gt; b[1..j-1] &amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt; d[i][j-1] &amp;lt;/tex&amp;gt; уже посчитан).&lt;br /&gt;
*Если &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то одним дополнительным циклом пробежим по &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; и найдём предыдущий элемент НОВП, оканчивающейся в &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; (он меньше &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt;). Из подходящих элементов выберем тот, для которого &amp;lt;tex&amp;gt; d[k][j] &amp;lt;/tex&amp;gt; - максимальна.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi=&amp;quot;120&amp;quot;&amp;gt; d[i][j] = \max\limits_{k = 1..i-1} d[k][j] + 1 &amp;lt;/tex&amp;gt; при условии, что &amp;lt;tex&amp;gt; a[k] &amp;lt; a[i].&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Длина НОВП будет в элементе с максимальным значением &amp;lt;tex&amp;gt; d[i][m] &amp;lt;/tex&amp;gt;. Для восстановления ответа будем хранить массив предков по массиву &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;, как и в предыдущем решении.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;int&amp;gt; '''LCIS'''(vector&amp;lt;int&amp;gt; a, vector&amp;lt;int&amp;gt; b)&lt;br /&gt;
   d = int[n][m]&lt;br /&gt;
   prev = int[n]&lt;br /&gt;
   '''for''' i = 1...n &lt;br /&gt;
     '''for''' j = 1...m&lt;br /&gt;
       '''if''' a[i] == b[j]&lt;br /&gt;
         d[i][j] = 1   // НОВП как минимум 1, состоит из одного элемента a[i] &amp;lt;-&amp;gt; b[j]&lt;br /&gt;
         '''for''' k = 1...i-1&lt;br /&gt;
           '''if''' a[k] &amp;lt; a[i] '''and''' d[i][j] &amp;lt; d[k][j] + 1&lt;br /&gt;
             d[i][j] = d[k][j] + 1&lt;br /&gt;
             prev[i] = k&lt;br /&gt;
       '''else'''&lt;br /&gt;
         d[i][j] = d[i][j-1] &lt;br /&gt;
   // восстановление&lt;br /&gt;
   pos = 1         // ищем элемент c максимальным d[pos][m]&lt;br /&gt;
   '''for''' i = 1...n&lt;br /&gt;
     '''if''' d[pos][m] &amp;lt; d[i][m]&lt;br /&gt;
       pos = i&lt;br /&gt;
   vector&amp;lt;int&amp;gt; answer&lt;br /&gt;
   '''while''' pos != 0&lt;br /&gt;
     answer.push(a[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Решение за время O(N&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;)==&lt;br /&gt;
Модифицируем предыдущее решение, добавив небольшую &amp;quot;хитрость&amp;quot;. Теперь &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; - это длина наибольшей общей возрастающей подпоследовательности префиксов &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;, причем элемент &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; - последний представитель НОВП массива &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; может не быть последним в массиве &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt;. Вычислять &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; будем всё так же: сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, а при равенстве - по увеличению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Тогда для очередного значения &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; есть два варианта:&lt;br /&gt;
*&amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; не входит в НОВП. Тогда &amp;lt;tex&amp;gt; d[i][j] = d[i-1][j] &amp;lt;/tex&amp;gt;: значение динамики уже посчитано на префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
*&amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; входит в НОВП. Это значит, что &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, то есть для подсчёта &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; нужно пробегать циклом по &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt; в поисках элемента &amp;lt;tex&amp;gt; b[k] &amp;lt; b[j] &amp;lt;/tex&amp;gt; с наибольшим значением &amp;lt;tex&amp;gt; d[i-1][k] &amp;lt;/tex&amp;gt;. Но мы считаем &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt; сначала по увеличению &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt;, поэтому будем считать &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; ''фиксированным''. Чтобы не запускать цикл при каждом равенстве &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; элементу &amp;lt;tex&amp;gt; b[k] &amp;lt;/tex&amp;gt;, в дополнительной переменной &amp;lt;tex&amp;gt; best &amp;lt;/tex&amp;gt; будем хранить &amp;quot;лучший&amp;quot; элемент (и его индекс &amp;lt;tex&amp;gt; ind &amp;lt;/tex&amp;gt; в массиве &amp;lt;tex&amp;gt; b &amp;lt;/tex&amp;gt;) такой, что этот элемент строго меньше &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; (а также меньше &amp;lt;tex&amp;gt; b[k] &amp;lt;/tex&amp;gt;) и значение динамики для него максимально: &amp;lt;tex&amp;gt; b[ind] &amp;lt; a[i] = b[k] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; best = d[i-1][ind] \rightarrow max. &amp;lt;/tex&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 vector&amp;lt;int&amp;gt; '''LCIS'''(vector&amp;lt;int&amp;gt; a, vector&amp;lt;int&amp;gt; b)&lt;br /&gt;
   d = int[n][m]   // динамика&lt;br /&gt;
   prev = int[n]   // массив предков &lt;br /&gt;
   '''for''' i = 1...n&lt;br /&gt;
     ind = 0       // позиция &amp;quot;лучшего&amp;quot; элемента в массиве b&lt;br /&gt;
     best = 0      // значение динамики для &amp;quot;лучшего&amp;quot; элемента&lt;br /&gt;
     '''for''' j = 1...m	&lt;br /&gt;
       d[i][j] = d[i-1][j]                          // НОВП на a[1..i-1] и b[1..j] (без элемента a[i])&lt;br /&gt;
       '''if''' a[i] == b[j] '''and''' d[i-1][j] &amp;lt; best + 1   // используем a[i]-й элемент для увеличения НОВП&lt;br /&gt;
         d[i][j] = best + 1                         &lt;br /&gt;
         prev[j] = ind                            &lt;br /&gt;
       '''if''' a[i] &amp;gt; b[j] '''and''' d[i-1][j] &amp;gt; best // при следующем равенстве a[i] == b[j']&lt;br /&gt;
         best = d[i-1][j]                  // в best будет храниться &amp;quot;лучший&amp;quot; элемент:            &lt;br /&gt;
         ind = j                           // b[ind] &amp;lt; b[j'] и d[i][ind] &amp;lt;tex&amp;gt; \rightarrow &amp;lt;/tex&amp;gt; max&lt;br /&gt;
   // восстановление (по массиву b)&lt;br /&gt;
   pos = 1         // ищем лучший элемент d[n][pos] &amp;lt;tex&amp;gt; \rightarrow &amp;lt;/tex&amp;gt; max&lt;br /&gt;
   '''for''' j = 1...m&lt;br /&gt;
     '''if''' d[n][pos] &amp;lt; d[n][j]&lt;br /&gt;
       pos = j&lt;br /&gt;
   vector&amp;lt;int&amp;gt; answer&lt;br /&gt;
   '''while''' pos != 0  // проходим по массиву b, выписывая элементы НОВП&lt;br /&gt;
     answer.push(b[pos])&lt;br /&gt;
     pos = prev[pos]&lt;br /&gt;
   '''return''' answer&lt;br /&gt;
&lt;br /&gt;
=== Доказательство оптимальности ===&lt;br /&gt;
В данной задаче используется принцип оптимальности на префиксе. Использование дополнительной переменной для подсчета всех случаев &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt; не влияет на корректность алгоритма - это всего лишь уловки реализации. Поэтому покажем, что для вычисления очередного значения &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; мы используем оптимальность на подзадачах и обращаемся к уже посчитанным значениям. &lt;br /&gt;
Напомним, как обозначается динамика: &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; - это НОВП на префиксах &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;, где последним элементом НОВП является элемент &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; может не быть равен &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; (то есть элемент &amp;lt;tex&amp;gt; a[i'] = b[j] &amp;lt;/tex&amp;gt; лежит где-то в префиксе &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt;). Итак, для &amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt; есть два варианта:&lt;br /&gt;
* &amp;lt;tex&amp;gt; a[i] \neq b[j] &amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; не влияет на результат, и последний элемент НОВП &amp;lt;tex&amp;gt; a[i'] = b[j] &amp;lt;/tex&amp;gt;  лежит в &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; a[i] = b[j] &amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; - последние элементы НОВП префиксов &amp;lt;tex&amp;gt; a[1..i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j] &amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; - по определению динамики, а &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; как элемент, который может стать последним, не ухудшая результат. Действительно, последовательность строго возрастает, поэтому если в префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; есть элемент &amp;lt;tex&amp;gt; a[k] = b[j] &amp;lt;/tex&amp;gt;, то его можно заменить на элемент &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; без уменьшения длины НОВП. Если же в &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; такого элемента нет, то &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; - единственный из возможных вариантов. Итак, &amp;lt;tex&amp;gt; a[i] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[j] &amp;lt;/tex&amp;gt; - последние элементы НОВП. Значит, начало НОВП (&amp;lt;tex&amp;gt; d[i][j] &amp;lt;/tex&amp;gt;) лежит в префиксах &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; b[1..j-1] &amp;lt;/tex&amp;gt; (значения для которых уже посчитаны). Мы ищем элемент &amp;lt;tex&amp;gt; b[k] &amp;lt; b[j] &amp;lt;/tex&amp;gt; с лучшей динамикой &amp;lt;tex&amp;gt; d[i-1][k] &amp;lt;/tex&amp;gt;, что удовлетворяет условию возрастания последовательности и автоматически гарантирует, что конец такой НОВП лежит в префиксе &amp;lt;tex&amp;gt; a[1..i-1] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
&lt;br /&gt;
*[[Задача о наибольшей общей подпоследовательности]]&lt;br /&gt;
*[[Задача о наибольшей возрастающей подпоследовательности]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
[http://codeforces.ru/contest/10/problem/D Codeforces {{---}} Задача о наибольшей общей возрастающей подпоследовательности]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=58851</id>
		<title>Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%BC_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D0%BE%D0%BC_%D0%BA%D0%BE%D0%B4%D0%B5_%D1%81_%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC_%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%B0._%D0%9C%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D1%82%D0%BE%D1%87%D0%BA%D0%B8_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B7%D0%B0&amp;diff=58851"/>
				<updated>2017-01-05T19:11:13Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Заменил ссылку; заменил дефисы на тире;взял переменные и константы в Тех; исправил знаки неравенств; оформил источники информации&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Определение ==&lt;br /&gt;
{{Определение &lt;br /&gt;
| definition =&lt;br /&gt;
[[Оптимальный префиксный код с длиной кодового слова не более L бит|Оптимальный префиксный код]] с сохранением порядка (англ. ''order-preserving code'', ''alphabetic code'').&lt;br /&gt;
 &lt;br /&gt;
Пусть у нас есть алфавит &amp;lt;tex&amp;gt; \Sigma &amp;lt;/tex&amp;gt;. Каждому символу &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; сопоставим его код &amp;lt;tex&amp;gt; p_i &amp;lt;/tex&amp;gt;. Кодирование называется оптимальным префиксным с сохранением порядка (алфавитным), если соблюдаются:&lt;br /&gt;
# Условие порядка {{---}} &amp;lt;tex&amp;gt; \forall i, j : c_i &amp;lt; c_j \iff p_i &amp;lt; p_j &amp;lt;/tex&amp;gt;. То есть, если символ &amp;lt;tex&amp;gt;c_i &amp;lt;/tex&amp;gt; лексикографически меньше символа &amp;lt;tex&amp;gt; c_j &amp;lt;/tex&amp;gt;, его код также будет [[лексикографический порядок | лексикографически]] меньше, и наоборот.&lt;br /&gt;
# Условие оптимальности {{---}} &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^{|\Sigma|} f_i \cdot |p_i| &amp;lt;/tex&amp;gt; {{---}} минимально, где &amp;lt;tex&amp;gt; f_i &amp;lt;/tex&amp;gt; {{---}} частота встречаемости символа &amp;lt;tex&amp;gt; c_i &amp;lt;/tex&amp;gt; в тексте, а &amp;lt;tex&amp;gt; |p_i| &amp;lt;/tex&amp;gt; {{---}} длина его кода.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Решим задачу, используя ДП на подотрезках. Пусть в ячейке &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; хранится минимальная стоимость кодового дерева для отрезка алфавита от &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда пересчет &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt; будет происходить так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; D[i][j] = \min\limits_{k = i}^{j - 1} \left ( D[i][k] + D[k + 1][j] \right ) + w[i][j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Базой динамики будет &amp;lt;tex&amp;gt; D[i][i] = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Добавочный член &amp;lt;tex&amp;gt;w[i][j] = \sum\limits_{t = i}^{j} f_t &amp;lt;/tex&amp;gt; возникает от того что каждым объединением двух подотрезков мы увеличиваем высоту дерева на 1, а значит, и длины всех кодов символов &amp;lt;tex&amp;gt; c_i .. c_j &amp;lt;/tex&amp;gt; также увеличиваются на 1.&lt;br /&gt;
&lt;br /&gt;
Тогда такое ''наибольшее'' &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, на котором достигается этот минимум, называется точкой разреза для отрезка &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;. Пусть в ячейке &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; хранится точка разреза на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если разрез происходит по какому-то определенному индексу &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; , такой разрез обозначим &amp;lt;tex&amp;gt; D_q[i][j] &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, получили алгоритм, работающий за &amp;lt;tex&amp;gt; O(n^3) &amp;lt;/tex&amp;gt;. Коды каждого символа можно легко получить так же, как в алгоритме Хаффмана {{---}} обходом по построенному дереву.&lt;br /&gt;
&lt;br /&gt;
Если доказать монотонность точки разреза, то можно уменьшить асимптотику алгоритма до &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Монотонность точки разреза ==&lt;br /&gt;
Для доказательства этого сперва докажем несколько лемм.&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
| definition=&lt;br /&gt;
Функция &amp;lt;tex&amp;gt; a &amp;lt;/tex&amp;gt; удовлетворяет '''неравенству четырехугольника''' (англ. ''quadrangle inequation''), если&lt;br /&gt;
: &amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : a[i][j] + a[i'][j'] \leqslant a[i'][j] + a[i][j']&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
&amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника.&lt;br /&gt;
| proof=&lt;br /&gt;
Заметим, что &amp;lt;tex&amp;gt; w[i][j] = w[i][t] + w[t+1][j] &amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt; w[i][j] &amp;lt;/tex&amp;gt; {{---}} простая арифметическая сумма. Тогда:&lt;br /&gt;
: &amp;lt;tex&amp;gt; w[i][j] + w[i'][j'] \leqslant w[i'][j] + w[i][j']&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][i' - 1] + w[i'][j]) + (w[i'][j] + w[j + 1][j']) \leqslant (w[i'][j]) + (w[i][i' - 1] + w[i'][j] + w[j + 1][j']) &amp;lt;/tex&amp;gt;&lt;br /&gt;
Получили &amp;lt;tex&amp;gt; 0 \leqslant 0 &amp;lt;/tex&amp;gt;, что является верным. Лемма доказана.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt; также удовлетворяет неравенству четырехугольника, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\forall i \leqslant i' \leqslant j \leqslant j' : D[i][j] + D[i'][j'] \leqslant D[i'][j] + D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
| proof=&lt;br /&gt;
При &amp;lt;tex&amp;gt; i = i' &amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt; j = j' &amp;lt;/tex&amp;gt;, очевидно, неравенство выполняется.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' = j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' = j &amp;lt; j' &amp;lt;/tex&amp;gt;. Тогда неравенство четырехугольника сводится к:&lt;br /&gt;
#: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; k = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \leqslant j &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i][j] + D[j][j'] \leqslant w[i][j] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j] + D[j][j'] &amp;lt;/tex&amp;gt; {{---}} так как &amp;lt;tex&amp;gt; w[i][j'] \geqslant w[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + D[i][k-1] + D[k][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D[i][j'] &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; k \geqslant j &amp;lt;/tex&amp;gt; {{---}} аналогичный предыдущему случай.&lt;br /&gt;
# &amp;lt;tex&amp;gt; i' &amp;lt; j &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: &amp;lt;tex&amp;gt; i &amp;lt; i' &amp;lt; j &amp;lt; j' &amp;lt;/tex&amp;gt; &lt;br /&gt;
#: Пусть &amp;lt;tex&amp;gt; y = R[i'][j] &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; z = R[i][j'] &amp;lt;/tex&amp;gt;. Получили два симметричных случая:&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \leqslant y &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: Получили &amp;lt;tex&amp;gt; i \leqslant z \leqslant y \leqslant j &amp;lt;/tex&amp;gt;. Запишем:&lt;br /&gt;
##: &amp;lt;tex&amp;gt; D[i'][j'] + D[i][j] \leqslant D_y[i'][j'] + D_z[i][j] = w[i'][j'] + D[i'][y-1] + D[y][j'] + w[i][j] + D[i][z-1] + D[z][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[z][j] + D[y][j'] &amp;lt;/tex&amp;gt; {{---}} по неравенству четырехугольника для &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant w[i][j'] + w[i'][j] + D[i'][y-1] + D[i][z-1] + D[y][j] + D[z][j'] &amp;lt;/tex&amp;gt; {{---}} по индукционному предположению для &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
##: &amp;lt;tex&amp;gt; \leqslant D[i][j'] + D[i'][j] &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
## &amp;lt;tex&amp;gt; z \geqslant y &amp;lt;/tex&amp;gt; доказывается аналогично.&lt;br /&gt;
Лемма доказана.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
| about=&lt;br /&gt;
Монотонность точки разреза&lt;br /&gt;
| statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt; w &amp;lt;/tex&amp;gt; удовлетворяет неравенству четырехугольника, то:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \forall i \leqslant j : R[i][j] \leqslant R[i][j+1] \leqslant R[i+1][j+1] &amp;lt;/tex&amp;gt;  &lt;br /&gt;
| proof=&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; i = j &amp;lt;/tex&amp;gt; неравенство, очевидно, выполняется. Рассматриваем случай &amp;lt;tex&amp;gt; i &amp;lt; j &amp;lt;/tex&amp;gt; и только случай &amp;lt;tex&amp;gt; R[i][j] \leqslant R[i][j+1] &amp;lt;/tex&amp;gt;(вторая часть доказывается аналогично):&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; {{---}} максимальный индекс, в котором достигается минимум, достаточно показать, что:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: [D_{k'}[i][j] \leqslant D_k[i][j]] \Rightarrow [D_{k'}[i][j+1] \leqslant D_k[i][j+1]] &amp;lt;/tex&amp;gt; {{---}} фактически, это означает что если на отрезке &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt; разрез оптимальнее по &amp;lt;tex&amp;gt; k' &amp;lt;/tex&amp;gt;, чем по &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt;, то он также будет оптимальнее и на отрезке &amp;lt;tex&amp;gt; i..j+1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Докажем более сильное неравенство:&lt;br /&gt;
: &amp;lt;tex&amp;gt; \forall i &amp;lt; k \leqslant k' \leqslant j: D_k[i][j] - D_{k'}[i][j] \leqslant D_k[i][j+1] - D_{k'}[i][j+1] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D_k[i][j] + D_{k'}[i][j+1] \leqslant D_k[i][j+1] + D_{k'}[i][j] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; (w[i][j] + D[i][k-1] + D[h][j]) + (w[i][j+1] + D[i][k'-1] + D[k][j+1]) \leqslant (w[i][j+1] + D[i][k-1] + D[k][j+1]) + (w[i][j] + D[i][k'-1] + D[k'][j]) &amp;lt;/tex&amp;gt; {{---}} по определению &amp;lt;tex&amp;gt; D &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; D[k][j] + D[k'][j+1] \leqslant D[k][j+1] + D[k'][j] &amp;lt;/tex&amp;gt; {{---}} получили неравенство четырехугольника для &amp;lt;tex&amp;gt; k \leqslant k' \leqslant j \leqslant j+1 &amp;lt;/tex&amp;gt;, что является верным из предыдущей леммы. Теорема доказана.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Объяснение квадратичной асимптотики ==&lt;br /&gt;
Рассмотрим матрицу &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt;. Так как отрезки &amp;lt;tex&amp;gt; i..j &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; i &amp;gt; j &amp;lt;/tex&amp;gt; мы не рассматриваем, она будет верхнетреугольной. Вначале она будет заполнена так, что &amp;lt;tex&amp;gt; R[i][i] = i &amp;lt;/tex&amp;gt;(так как для отрезка, состоящего из одного элемента, он же и является точкой разреза). Далее, для любого элемента &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt; его значения лежат между &amp;lt;tex&amp;gt; R[i][j-1] &amp;lt;/tex&amp;gt; (левый элемент в матрице) и &amp;lt;tex&amp;gt; R[i+1][j] &amp;lt;/tex&amp;gt; (нижний элемент в матрице). Так как мы используем динамику по подотрезкам, то сначала мы рассчитаем &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; для отрезков длины 2, затем 3, и так далее до n. Фактически, мы будем обходить диагонали матрицы, количество которых равно n.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим элемент &amp;lt;tex&amp;gt; R[i][j] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i][j-1] \leqslant R[i][j] \leqslant R[i+1][j] &amp;lt;/tex&amp;gt;. Следующий элемент, который мы будем пересчитывать {{---}} &amp;lt;tex&amp;gt; R[i+1][j+1] &amp;lt;/tex&amp;gt;. Для него выполняется &amp;lt;tex&amp;gt; R[i+1][j] \leqslant R[i+1][j+1] \leqslant R[i+2][j+1] &amp;lt;/tex&amp;gt;. Таким образом, заполняя одну диагональ, алгоритм сделает не более n шагов, а так как диагоналей n, получили асимптотику &amp;lt;tex&amp;gt; O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Источники информации ==&lt;br /&gt;
[http://www.cs.ust.hk/mjg_lib/Library/Tut_BST.pdf S.V. Nagaraj {{---}} Tutorial: Optimal binary search trees]&lt;br /&gt;
&lt;br /&gt;
''Кнут Д.Э.'' {{---}} Искусство программирования, том 3. Сортировка и поиск. — М.: «Вильямс», 2005.&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D1%8B%D1%85_%D0%BF%D0%BE%D0%B4%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8F%D1%85,_%D1%82%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%BE_%D1%81%D0%B2%D1%8F%D0%B7%D0%B8_%D0%B4%D0%BB%D0%B8%D0%BD%D1%8B_%D0%9D%D0%92%D0%9F_%D0%B8_%D0%9D%D0%A3%D0%9F&amp;diff=58841</id>
		<title>Задача о монотонных подпоследовательностях, теорема о связи длины НВП и НУП</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0_%D0%BE_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D1%8B%D1%85_%D0%BF%D0%BE%D0%B4%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8F%D1%85,_%D1%82%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%BE_%D1%81%D0%B2%D1%8F%D0%B7%D0%B8_%D0%B4%D0%BB%D0%B8%D0%BD%D1%8B_%D0%9D%D0%92%D0%9F_%D0%B8_%D0%9D%D0%A3%D0%9F&amp;diff=58841"/>
				<updated>2017-01-05T17:58:14Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Добавил англ. терминов; взял определение в шаблон; заменил дефисы на тире; правильно оформил источники информации.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Последовательность''' (англ. ''sequence'') {{---}} это набор элементов некоторого множества пронумерованный натуральными числами. Последовательность является результатом последовательного выбора элементов множества. При этом элементы последовательности могут повторяться. В частности, последовательность не является подмножеством заданного множества.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Определения ==&lt;br /&gt;
&lt;br /&gt;
Последовательность &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; элементов множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; называется '''''неубывающей''''' (англ. ''nondecreasing''), если каждый элемент этой последовательности не превосходит следующего за ним.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; &amp;amp;mdash; '''''неубывающая''''' &amp;lt;tex&amp;gt;\Leftrightarrow\forall n \in \mathbb N: x_n \leqslant x_{n+1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; элементов множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; называется '''''невозрастающей''''' (англ. ''nonincreasing''), если каждый следующий элемент этой последовательности не превосходит предыдущего.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; &amp;amp;mdash; '''''невозрастающая''''' &amp;lt;tex&amp;gt;\Leftrightarrow\forall n \in \mathbb N: x_n \geqslant x_{n+1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; элементов множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; называется '''''возрастающей''''' (англ. ''increasing''), если каждый следующий элемент этой последовательности превышает предыдущий.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; &amp;amp;mdash; '''''возрастающая''''' &amp;lt;tex&amp;gt;\Leftrightarrow\forall n \in \mathbb N: x_n &amp;lt; x_{n+1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность &amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; элементов множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; называется '''''убывающей''''' (англ. ''decreasing''), если каждый элемент этой последовательности превышает следующий за ним.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\{x_n\}&amp;lt;/tex&amp;gt; &amp;amp;mdash; '''''убывающая''''' &amp;lt;tex&amp;gt;\Leftrightarrow\forall n \in \mathbb N: x_n &amp;gt; x_{n+1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность называется '''монотонной''' (англ. ''monotonic''), если она является неубывающей, либо невозрастающей.&lt;br /&gt;
&lt;br /&gt;
Последовательность называется '''строго монотонной''' (англ. ''strictly monotonic''), если она является возрастающей, либо убывающей.&lt;br /&gt;
&lt;br /&gt;
Очевидно, что строго монотонная последовательность является монотонной.&lt;br /&gt;
&lt;br /&gt;
== Теорема о связи длины НВП и НУП ==&lt;br /&gt;
&lt;br /&gt;
{{&lt;br /&gt;
Теорема&lt;br /&gt;
|author=&lt;br /&gt;
|about=&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; {{---}} перестановка чисел длины &amp;lt;tex&amp;gt;n, l&amp;lt;/tex&amp;gt; {{---}} длина наибольшей возрастающей подпоследовательности (НВП), &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; {{---}} длина наибольшей убывающей подпоследовательности (НУП). Тогда &amp;lt;tex&amp;gt;l k \geqslant n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим два массива длины &amp;lt;tex&amp;gt;n : S &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; T &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; S_i &amp;lt;/tex&amp;gt; {{---}} длина НВП, которая заканчивается на &amp;lt;tex&amp;gt;a_i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; T_i &amp;lt;/tex&amp;gt; {{---}} длина НУП, которая начинается на &amp;lt;tex&amp;gt;a_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Докажем, что все пары &amp;lt;tex&amp;gt;(S_i, T_i)&amp;lt;/tex&amp;gt; различны.&lt;br /&gt;
Пусть существуют такие &amp;lt;tex&amp;gt;i &amp;lt; j&amp;lt;/tex&amp;gt; , что &amp;lt;tex&amp;gt; S_i &amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt; S_j &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; T_i &amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt; T_j&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;a_i &amp;lt; a_j&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt; a_j &amp;lt;/tex&amp;gt; можно добавить к НВП, заканчивающейся на &amp;lt;tex&amp;gt; a_i &amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;S_j \geqslant S_i + 1&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;a_i &amp;gt; a_j&amp;lt;/tex&amp;gt;, то по аналогии &amp;lt;tex&amp;gt;T_i \geqslant T_j + 1&amp;lt;/tex&amp;gt;. Противоречие! Следовательно все такие пары различны.&lt;br /&gt;
&lt;br /&gt;
Заметим что &amp;lt;tex&amp;gt;1 \leqslant S_i \leqslant l, 1 \leqslant T_i \leqslant k&amp;lt;/tex&amp;gt;, поэтому существуют &amp;lt;tex&amp;gt;l k&amp;lt;/tex&amp;gt; различных пар &amp;lt;tex&amp;gt; (S_i, T_i) &amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;l k &amp;lt; n&amp;lt;/tex&amp;gt; тогда среди &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; пар найдутся две одинаковые. Такого быть не может по доказанному выше, т. е. &amp;lt;tex&amp;gt;l k \geqslant n&amp;lt;/tex&amp;gt;, ч. т. д.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Следствие из теоремы ==&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина последовательности, тогда длина наибольшей монотонной подпоследовательности не меньше &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C#.D0.9D.D0.B5.D0.BA.D0.BE.D1.82.D0.BE.D1.80.D1.8B.D0.B5_.D0.B2.D0.B8.D0.B4.D1.8B_.D0.BF.D0.BE.D1.81.D0.BB.D0.B5.D0.B4.D0.BE.D0.B2.D0.B0.D1.82.D0.B5.D0.BB.D1.8C.D0.BD.D0.BE.D1.81.D1.82.D0.B5.D0.B9 Википедия {{---}} Последовательность]&lt;br /&gt;
&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Longest_increasing_subsequence Wikipedia {{---}} Longest increasing subsequence]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Комбинаторика ]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%B0%D1%81%D0%BA%D0%B0%D0%B4%D0%BD%D1%8B%D0%B9_%D1%81%D1%83%D0%BC%D0%BC%D0%B0%D1%82%D0%BE%D1%80&amp;diff=58836</id>
		<title>Каскадный сумматор</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%B0%D1%81%D0%BA%D0%B0%D0%B4%D0%BD%D1%8B%D0%B9_%D1%81%D1%83%D0%BC%D0%BC%D0%B0%D1%82%D0%BE%D1%80&amp;diff=58836"/>
				<updated>2017-01-05T17:25:45Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Добавил англ. терминов; правильно оформил источники информации.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Каскадный сумматор''' (англ. ''ripple-carry adder'') {{---}} логическая [[Реализация булевой функции схемой из функциональных элементов|схема]], осуществляющая сложение многоразрядных двоичных чисел.&lt;br /&gt;
}}&lt;br /&gt;
Как известно, с помощью [[Сумматор|полного сумматора]] можно сложить 2 одноразрядных двоичных числа. Для сложения двух &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-разрядных двоичных чисел можно использовать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; полных сумматоров.&lt;br /&gt;
&lt;br /&gt;
При сложении двух чисел в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-том разряде складываются &amp;lt;TeX&amp;gt;a_i&amp;lt;/TeX&amp;gt;, &amp;lt;Tex&amp;gt;b_i&amp;lt;/TeX&amp;gt; и входной бит переноса (англ. ''carry-in bit'')  &amp;lt;TeX&amp;gt;c_i&amp;lt;/TeX&amp;gt;. Младший разряд суммы записывается в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-й разряд ответа (&amp;lt;TeX&amp;gt;s_i&amp;lt;/TeX&amp;gt;), а старший становится выходным битом переноса (англ. ''carry-out bit'')  &amp;lt;TeX&amp;gt;c_{i+1}&amp;lt;/TeX&amp;gt; и используется при сложении в следующем разряде.&lt;br /&gt;
&lt;br /&gt;
При этом в первый входной бит переноса подаётся ноль, а последний бит переноса даёт старший разряд суммы.&lt;br /&gt;
&lt;br /&gt;
Прежде чем сложить &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ые биты, надо ждать выходного бита переноса от сложения &amp;lt;tex&amp;gt; i-1 &amp;lt;/tex&amp;gt; битов, то есть сумма в каждом разряде может зависеть от суммы предыдущих разрядов. Поэтому сложение с помощью каскадного сумматора выполняется за время &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Ripple_carry_adder.png]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Сумматор]]&lt;br /&gt;
*[[Двоичный каскадный сумматор]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Adder_(electronics) Wikipedia {{---}} Adder (electronics)]&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/arithmetics/binary-addition-2002/algorithm Каскадное сложение]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Схемы из функциональных элементов ]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D1%83%D0%BF%D0%B5%D1%80%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D0%B8&amp;diff=58833</id>
		<title>Суперпозиции</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D1%83%D0%BF%D0%B5%D1%80%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D0%B8&amp;diff=58833"/>
				<updated>2017-01-05T16:57:45Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Добавил англ. терминов.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Суперпозиция функций''' (или '''сложная функция''', или '''композиция функций''', англ. ''function composition'') {{---}} это функция, полученная из некоторого множества функций путем подстановки одной функции в другую или отождествления переменных.&lt;br /&gt;
}}&lt;br /&gt;
Множество всех возможных не эквивалентных друг другу суперпозиций данного множества функций образует [[Представление функции формулой, полные системы функций|замыкание]] данного множества функций.&lt;br /&gt;
&lt;br /&gt;
== Способы получения суперпозиций ==&lt;br /&gt;
Рассмотрим две [[Определение булевой функции|булевы функции]]:&lt;br /&gt;
функцию &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; аргументов &amp;lt;tex&amp;gt;f(x_{1}, x_{2}, ..., x_{n})&amp;lt;/tex&amp;gt; и&lt;br /&gt;
функцию &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; аргументов &amp;lt;tex&amp;gt;g(y_{1}, y_{2}, ..., y_{m})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Тогда мы можем получить новую функцию из имеющихся двумя способами:&lt;br /&gt;
#Подстановкой одной функции в качестве некоторого аргумента для другой;&lt;br /&gt;
#Отождествлением аргументов функций.&lt;br /&gt;
&lt;br /&gt;
=== Подстановка одной функции в другую ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Подстановкой''' (англ. ''substitution'') функции &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; в функцию &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; называется замена &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-того аргумента функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; значением функции &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;h(x_{1}, ..., x_{n+m-1}) = f(x_{1}, ..., x_{i-1}, g(x_{i}, ..., x_{i+m-1}), x_{i+m}, ..., x_{n+m-1})&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Допускается также не только подстановка одной функции в другую, но и подстановка функции в саму себя.&lt;br /&gt;
&lt;br /&gt;
При подстановке функции &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; вместо &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-того аргумента функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt;, результирующая функция &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; будет принимать аргументы, которые можно разделить на следующие блоки:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
 |1. &amp;lt;tex&amp;gt; x_{1}, ..., x_{i-1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |{{---}} аргументы функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; до подставленного значения функции &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |2. &amp;lt;tex&amp;gt; x_{i}, ..., x_{i+m-1}   &amp;lt;/tex&amp;gt;&lt;br /&gt;
 |{{---}} используются как аргументы для вычисления значения функции &amp;lt;tex&amp;gt;g(y_{1}, ..., y_{m})&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |-&lt;br /&gt;
 |3. &amp;lt;tex&amp;gt; x_{i+m}, ..., x_{n+m-1} &amp;lt;/tex&amp;gt;&lt;br /&gt;
 |{{---}} аргументы функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; после подставленного значения функции &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
'''Пример:'''&lt;br /&gt;
&lt;br /&gt;
Исходные функции:&lt;br /&gt;
#&amp;lt;tex&amp;gt; f(a,b) = a \vee b &amp;lt;/tex&amp;gt;&lt;br /&gt;
#&amp;lt;tex&amp;gt; g(a)   = \neg a &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; h(a,b) = f(a,g(b)) = a \vee \neg b &amp;lt;/tex&amp;gt; {{---}} подстановка функции &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; вместо второго аргумента функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt;. В данном примере при помощи подстановки мы получили функцию &amp;lt;tex&amp;gt;h(a,b)=a \leftarrow b&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Отождествление переменных ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Отождествлением переменных''' (англ. ''identification of variables'') называется подстановка &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-того аргумента функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; вместо &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-того аргумента:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;h(x_{1}, ..., x_{j-1}, x_{j+1}, ..., x_{n}) = f(x_{1}, ..., x_{i}, ..., x_{j-1}, x_{i}, x_{j+1}, ..., x_{n})&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, при отождествлении &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; переменных мы получаем функцию &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; с количеством аргументов &amp;lt;tex&amp;gt;n-c+1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Пример:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; f(a,b) = a \vee b &amp;lt;/tex&amp;gt; {{---}} исходная функция&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; h(a)   = a \vee a &amp;lt;/tex&amp;gt; {{---}} функция с отождествленными первым и вторым аргументами&lt;br /&gt;
&lt;br /&gt;
Очевидно, в данном примере мы получили функцию &amp;lt;tex&amp;gt;P_{1}&amp;lt;/tex&amp;gt; {{---}} проектор единственного аргумента.&lt;br /&gt;
&lt;br /&gt;
== Ранги суперпозиций ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ранг суперпозиции''' (англ. ''rank of function composition'') {{---}} это минимальное число подстановок и отождествлений, за которое суперпозиция может быть получена из исходного множества функций.&lt;br /&gt;
Суперпозиция &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt; ранга &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; обозначается как &amp;lt;tex&amp;gt;K^{n}&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Осипова В.А., Основы дискретной математики: Учебное пособие, М.: ФОРУМ: ИНФРА-М, 2006, стр 62-63&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Композиция_функций Композиция функций в математике]&lt;br /&gt;
*[http://mini-soft.ru/nstu/diskr/index.php Е.Л. Рабкин, Ю.Б. Фарфоровская, Дискретная математика, Глава 7: Суперпозиция функций. Замыкание набора функций. Замкнутые классы функций. Полные наборы. Базисы]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Булевы функции]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%9D%D0%A4&amp;diff=58831</id>
		<title>ДНФ</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%9D%D0%A4&amp;diff=58831"/>
				<updated>2017-01-05T16:17:35Z</updated>
		
		<summary type="html">&lt;p&gt;Max 27: Добавил англ. терминов; поправил аббревиатуры; убрал скобки в формулировке теоремы; выделил жирным шрифтом в определениях то, что нужно.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== ДНФ ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Простой конъюнкцией''' (англ. ''inclusive conjunction'') или '''конъюнктом''' (англ. ''conjunct'') называется конъюнкция одной или нескольких переменных или их отрицаний, причём каждая переменная встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
Простая конъюнкция&lt;br /&gt;
* '''полная''', если в неё каждая переменная (или её отрицание) входит ровно 1 раз;&lt;br /&gt;
* '''монотонная''', если она не содержит отрицаний переменных.&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Дизъюнктивная нормальная форма, ДНФ''' (англ. ''disjunctive normal form, DNF'') {{---}} нормальная форма, в которой [[Определение булевой функции|булева функция]] имеет вид дизъюнкции нескольких простых конъюнктов.&lt;br /&gt;
}}&lt;br /&gt;
Пример ДНФ:&lt;br /&gt;
&amp;lt;tex&amp;gt;f(x,y,z) = (x \land y) \lor (y \land \neg {z})&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== СДНФ ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Совершенная дизъюнктивная нормальная форма, СДНФ''' (англ. ''perfect disjunctive normal form, PDNF'') — это такая ДНФ, которая удовлетворяет условиям:&lt;br /&gt;
* в ней нет одинаковых простых конъюнкций&lt;br /&gt;
* каждая простая конъюнкция полная&lt;br /&gt;
}}&lt;br /&gt;
Пример СДНФ:&lt;br /&gt;
&amp;lt;tex&amp;gt;f(x,y,z) = (x \land \neg {y} \land z) \lor (x \land y \land \neg {z})&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Для любой булевой функции &amp;lt;tex&amp;gt;f(\vec {x})&amp;lt;/tex&amp;gt;, не равной тождественному нулю, существует СДНФ, ее задающая.&lt;br /&gt;
|proof = &lt;br /&gt;
Для любой булевой функции выполняется следующее соотношение, называемое '''разложением Шеннона'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f(\vec{x}) = \neg  x_i \wedge f(x_1, \dots ,x_{i-1},0,x_{i+1}, \dots ,x_n) \vee&lt;br /&gt;
x_i \wedge f(x_1, \dots ,x_{i-1},1,x_{i+1}, \dots ,x_n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Данное соотношение легко проверить подстановкой возможных значений &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). Эта формула позволяет выносить &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; за знак функции. Последовательно вынося &amp;lt;tex&amp;gt;x_1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;x_2&amp;lt;/tex&amp;gt;,.., &amp;lt;tex&amp;gt;x_n&amp;lt;/tex&amp;gt; за знак &amp;lt;tex&amp;gt;f(\vec{x})&amp;lt;/tex&amp;gt;, получаем следующую формулу : &lt;br /&gt;
&amp;lt;tex&amp;gt; f(\vec{x}) = \neg  x_1 \wedge \neg  x_2 \wedge ...\wedge \neg  x_{n-1} \wedge \neg  x_n \wedge f(0,0,...,0,0)~\vee~&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\neg  x_1 \wedge \neg  x_2 \wedge ... \wedge \neg  x_{n-1} \wedge x_n \wedge f(0,0,...,0,1) ~\vee~ \\&lt;br /&gt;
\dots \\&lt;br /&gt;
~\vee~ x_1 \wedge x_2 \wedge ... \wedge x_{n-1} \wedge \neg  x_n \wedge f(1,1,...,1,0) ~\vee~\\ &lt;br /&gt;
x_1 \wedge x_2 \wedge ... \wedge x_{n-1} \wedge x_n \wedge f(1,1,...,1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как применение данного соотношения к каждой из переменных увеличивает количество конъюнктов в два раза, то для функции от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных мы имеем &amp;lt;tex&amp;gt;2^n&amp;lt;/tex&amp;gt; конъюнктов. Каждый из них соответствует значению функции на одном из &amp;lt;tex&amp;gt;2^n&amp;lt;/tex&amp;gt; возможных наборов значений &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; переменных. Если на некотором наборе &amp;lt;tex&amp;gt;f(\vec{x})=0&amp;lt;/tex&amp;gt;, то весь соответствующий конъюнкт также равен нулю и из представления данной функции его можно исключить. Если же &amp;lt;tex&amp;gt; f(\vec{x})=1&amp;lt;/tex&amp;gt;, то в соответствующем конъюнкте само значение функции можно опустить. В результате для произвольной функции была построена СДНФ.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм построения СДНФ по таблице истинности ==&lt;br /&gt;
# В таблице истинности отмечаем те наборы переменных, на которых значение функции равно 1.&lt;br /&gt;
# Для каждого отмеченного набора записываем конъюнкцию всех переменных по следующему правилу: если значение некоторой переменной есть 1, то в конъюнкцию включаем саму переменную, иначе ее отрицание.&lt;br /&gt;
# Все полученные конъюнкции связываем операциями дизъюнкции.&lt;br /&gt;
&lt;br /&gt;
== Пример построения СДНФ для медианы==&lt;br /&gt;
1. В таблице истинности отмечаем те наборы переменных, на которых значение функции равно 1.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:10cm&amp;quot; border=1&lt;br /&gt;
|+&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#EEEEFF&lt;br /&gt;
| x || y || z || &amp;lt;tex&amp;gt; \langle x,y,z \rangle &amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 0 || 0 || 0&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 0 || 1 || 0&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 1 || 0 || 0&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 0 || 1 || 1 || 1&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 1 || 0 || 0 || 0&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 0 || 1 || 1&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 1 || 0 || 1&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
2. Для каждого отмеченного набора записываем конъюнкцию всех переменных по следующему правилу: если значение некоторой переменной есть 1, то в конъюнкцию включаем саму переменную, иначе ее отрицание.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;width:16cm&amp;quot; border=1&lt;br /&gt;
|+&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#EEEEFF&lt;br /&gt;
| x || y || z || &amp;lt;tex&amp;gt; \langle x,y,z \rangle &amp;lt;/tex&amp;gt; || &lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 0 || 0 || 0 ||&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 0 || 1 || 0 ||&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 0 || 1 || 0 || 0 ||&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 0 || 1 || 1 || 1 || &amp;lt;tex&amp;gt;(\neg {x} \land y \land z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
| 1 || 0 || 0 || 0 ||&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 0 || 1 || 1 || &amp;lt;tex&amp;gt;(x \land \neg {y} \land z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 1 || 0 || 1 || &amp;lt;tex&amp;gt;(x \land y \land \neg {z})&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-align=&amp;quot;center&amp;quot; bgcolor=#FFFFFF&lt;br /&gt;
! 1 || 1 || 1 || 1 || &amp;lt;tex&amp;gt;(x \land y \land z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
3. Все полученные конъюнкции связываем операциями дизъюнкции.&lt;br /&gt;
                                                                  &lt;br /&gt;
&amp;lt;tex&amp;gt; \langle x,y,z \rangle = (x \land y \land z) \lor (\neg {x} \land y \land z) \lor (x \land \neg {y} \land z) \lor (x \land y \land \neg {z})&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Примеры СДНФ для некоторых функций==&lt;br /&gt;
Стрелка Пирса: &amp;lt;tex&amp;gt; x \downarrow y = (\neg {x} \land \neg {y})&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Исключающее или: &amp;lt;tex&amp;gt; x \oplus y \oplus z = (\overline{x} \land \overline{y} \land z) \lor (\overline{x} \land y \land \overline{z}) \lor (x \land \overline{y} \land \overline{z}) \lor (x \land y \land z)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%A1%D0%94%D0%9D%D0%A4 СДНФ — Википедия]&lt;br /&gt;
* [http://dvo.sut.ru/libr/himath/w163rabk/index.htm Е.Л Рабкин,  Ю.Б. Фарфоровская — Дискретная математика]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Булевы функции ]]&lt;/div&gt;</summary>
		<author><name>Max 27</name></author>	</entry>

	</feed>