Задача о наибольшей общей палиндромной подпоследовательности — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
Строка 1: Строка 1:
 +
{| class="wikitable" align="center" style="color: red; background-color: black; font-size: 56px; width: 800px;"
 +
|+
 +
|-align="center"
 +
|'''НЕТ ВОЙНЕ'''
 +
|-style="font-size: 16px;"
 +
|
 +
24 февраля 2022 года российское руководство во главе с Владимиром Путиным развязало агрессивную войну против Украины. В глазах всего мира это военное преступление совершено от лица всей страны, всех россиян.
 +
 +
Будучи гражданами Российской Федерации, мы против своей воли оказались ответственными за нарушение международного права, военное вторжение и массовую гибель людей. Чудовищность совершенного преступления не оставляет возможности промолчать или ограничиться пассивным несогласием.
 +
 +
Мы убеждены в абсолютной ценности человеческой жизни, в незыблемости прав и свобод личности. Режим Путина — угроза этим ценностям. Наша задача — обьединить все силы для сопротивления ей.
 +
 +
Эту войну начали не россияне, а обезумевший диктатор. И наш гражданский долг — сделать всё, чтобы её остановить.
 +
 +
''Антивоенный комитет России''
 +
|-style="font-size: 16px;"
 +
|Распространяйте правду о текущих событиях, оберегайте от пропаганды своих друзей и близких. Изменение общественного восприятия войны - ключ к её завершению.
 +
|-style="font-size: 16px;"
 +
|[https://meduza.io/ meduza.io], [https://www.youtube.com/c/popularpolitics/videos Популярная политика], [https://novayagazeta.ru/ Новая газета], [https://zona.media/ zona.media], [https://www.youtube.com/c/MackNack/videos Майкл Наки].
 +
|}
 +
 
'''[[Задача о наибольшей общей подпоследовательности]]''' (англ. ''longest common subsequence (LCS)'') {{---}} классическая и хорошо изученная проблема.
 
'''[[Задача о наибольшей общей подпоследовательности]]''' (англ. ''longest common subsequence (LCS)'') {{---}} классическая и хорошо изученная проблема.
  

Версия 07:02, 1 сентября 2022

НЕТ ВОЙНЕ

24 февраля 2022 года российское руководство во главе с Владимиром Путиным развязало агрессивную войну против Украины. В глазах всего мира это военное преступление совершено от лица всей страны, всех россиян.

Будучи гражданами Российской Федерации, мы против своей воли оказались ответственными за нарушение международного права, военное вторжение и массовую гибель людей. Чудовищность совершенного преступления не оставляет возможности промолчать или ограничиться пассивным несогласием.

Мы убеждены в абсолютной ценности человеческой жизни, в незыблемости прав и свобод личности. Режим Путина — угроза этим ценностям. Наша задача — обьединить все силы для сопротивления ей.

Эту войну начали не россияне, а обезумевший диктатор. И наш гражданский долг — сделать всё, чтобы её остановить.

Антивоенный комитет России

Распространяйте правду о текущих событиях, оберегайте от пропаганды своих друзей и близких. Изменение общественного восприятия войны - ключ к её завершению.
meduza.io, Популярная политика, Новая газета, zona.media, Майкл Наки.

Задача о наибольшей общей подпоследовательности (англ. longest common subsequence (LCS)) — классическая и хорошо изученная проблема.

Задача о наибольшей подпоследовательности-палиндроме (англ. longest palindromic subsequence (LPS)) — также хорошо изучена.

Здесь мы рассмотрим задачу, которая объединяет две вышеперечисленные задачи в одну.

Определение:
Для последовательности [math]X[/math], мы обозначим её подпоследовательность [math]x_{i}...x_{j}\ (1 \leqslant i \leqslant j \leqslant n)\ [/math] как [math]X_{i,j}[/math]. Для двух последовательностей [math]X[/math] и [math]Y[/math], если общая подпоследовательность [math]Z[/math] последовательностей [math]X[/math] и [math]Y[/math] является палиндромом, то [math]Z[/math] называется общей подпалиндромной подпоследовательностью (англ. common palindromic subsequence). Общая подпалиндромная последовательность, имеющая максимальную длину, называется наибольшей общей подпалиндромной подпоследовательностью (англ. longest common palindromic subsequence (LCPS)) и мы обозначим её как [math]LCPS(X,Y)[/math].
Задача:
Наибольшая общая подпалиндромная подпоследовательность — задача, являющаяся интересным вариантом классической задачи о поиске наибольшей общей подпоследовательности, которая также накладывает условия, что эта подпоследовательность должна быть палиндромом.

Наивное решение

Можно придумать такое решение данной задачи: найти наибольшую общую подпоследовательность, в ней найти наибольшую подпалиндромную подпоследовательность. Но, к сожалению, это решение неверно.

Контрпример

Возьмем две последовательности [math]X=[1,\ 2,\ 3,\ 1][/math] и [math]Y=[1,\ 1,\ 2,\ 3][/math].

Наибольшей общая подпоследовательность данных последовательностей равна [math]LCS(X,Y) = [1,\ 2,\ 3][/math] и в ней наибольшая подпалиндромная последовательность имеет длину [math]1[/math].

Но очевидно, что на самом деле последовательность [math]Z=[1,\ 1][/math] является наибольшим общей палиндромной подпоследовательностью [math]X[/math] и [math]Y[/math] и имеет длину [math]2[/math].

Решение с помощью динамического программирования

Заметим, что в качестве подзадач для [math]LCPS[/math], в которых мы можем посчитать ответ, логично взять подпоследовательность от [math]X[/math] и от [math]Y[/math]. Основываясь на этом наблюдении мы сформулируем следующую теорему, которая доказывает оптимальную подструктуру свойств задачи [math]LCPS[/math], что даст возможность воспользоваться идеей динамического программирования.

Теорема:
Пусть [math]X[/math] и [math]Y[/math] — две последовательности длин [math]n[/math] и [math]m[/math] соответственно, а [math]X_{i,j}[/math] и [math]Y_{k,l}[/math] — две подпоследовательности последовательностей [math]X[/math] и [math]Y[/math] соответственно. Пусть [math]Z = z_{1}z_{2}...z_{u}[/math] — наибольшая общая подпалиндромная последовательность двух подпоследовательностей [math]X_{i,j}[/math] и [math]Y_{k,l}[/math]. Тогда выполняются следующие утверждения,
  1. Если [math]x_i=x_j=y_k=y_l=a[/math] (для произвольного [math]a[/math]), тогда [math]z_1=z_u=a[/math] и [math]Z_{2, u-1}[/math] — НОПП от подпоследовательностей [math]X_{i+1,j-1}[/math] и [math]Y_{k+1,l-1}[/math].
  2. Если [math]x_i=x_j=y_k=y_l[/math] не выполняется, то [math]Z[/math] — НОПП от подпоследовательностей ([math]X_{i+1,j}[/math] и [math]Y_{k,l}[/math]) или ([math]X_{i,j-1}[/math] и [math]Y_{k,l}[/math]) или ([math]X_{i,j}[/math] и [math]Y_{k+1,l}[/math]) или ([math]X_{i,j}[/math] и [math]Y_{k,l-1}[/math]).

На основании теоремы мы напишем следующую рекурсивную формулу для длины наибольшей общей подпалиндромной подпоследовательности:

[math] lcps[i,j,k,l] = \left\{\begin{array}{llcl} 0&&;&i \gt j\ \lor\ k \gt l\\ 1&&;&(i = j)\ \land\ (k = l)\ \land\ (x_i=x_j=y_k=y_l)\\ 2+lcps[i+1,j-1,k+1,l-1]&&;&(i \lt j)\ \land\ (k \lt l)\ \land\ (x_i=x_j=y_k=y_l)\\ \max{(}lcps[i+1,j,k,l],lcps[i,j-1,k,l],&&;&(i \leqslant j)\ \land\ (k \leqslant l)\ \land\ \lnot(x_i=x_j=y_k=y_l)\\ \:\:\:\:\:\:\:\:\:\:\:lcps[i,j,k+1,l],lcps[i,j,k,l-1]) \end{array}\right. [/math]

Где [math]lcps[i,j,k,l][/math] — длина наибольшей общей палиндромной подпоследовательности от [math]X_{i,j}[/math] и [math]Y_{k,l}[/math]. Длина наибольшей общей палиндромной подпоследовательности от последовательностей [math]X[/math] и [math]Y[/math] будет расположена в [math]lcps[1,n,1,m][/math]. Мы можем вычислить эту длину за время [math]O(n^4)[/math] используя динамическое программирование.

Реализация

Будем использовать динамику с запоминанием ответа (с мемоизацией). Оформим решения в виде рекурсивной функции [math]lcps[/math], которая возвращает ответ для подзадачи, на которую она была вызвана.
В массиве [math]\mathtt{ans}[/math] хранятся ответы для подзадач. До запуска функции [math]lcps[/math] заполним массив [math]ans[/math] значением [math]-1[/math]. Так как каждое значение считается не более одного раза и эта операция происходит за [math]O(1)[/math], мы получим асимптотику [math]O(n^4)[/math].

Псевдокод

int lcps(i: int, j: int, k: int, l: int)
  if (ans[i][j][k][l] [math] \neq [/math] -1) // если значение уже посчитано, то надо его вернуть
    return ans[i][j][k][l]
  if (i > j or k > l)
    ans[i][j][k][l] = 0
    return 0
  if (X[i] == X[j] == Y[k] == Y[l])
    if (i == j and k == l)
      ans[i][j][k][l] = 1
      return 1       
    else   
      ans[i][j][k][l] = (2 + lcps(i + 1, j - 1, k + 1, l - 1))    
      return ans[i][j][k][l]
  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))
  return ans[i][j][k][l]

См. также

Источники информации