Задача о наибольшей общей палиндромной подпоследовательности
Задача о наибольшей общей подпоследовательности (англ. longest common subsequence (LCS)) — классическая и хорошо изученная проблема.
Задача о наибольшей подпоследовательности-палиндроме (англ. longest palindromic subsequence (LPS)) - также хорошо изучена.
В этой статье мы рассмотрим задачу, которая объединяет две вышеперечисленные задачи в одну.
Наибольшая общая подпалиндромная подпоследовательность (англ. The longest common palindromic subsequence (LCPS)) — задача, являющаяся интересным вариантом классической задачи о поиске наибольшей общей подпоследовательности, которая находит наибольшую общую подпоследовательность среди двух последовательностей так, что она также является палиндромом.
Задача: |
Для последовательности | , мы обозначим его подпоследовательность как . Для двух последовательностей и , если общая подпоследовательность последовательностей и является палиндромом, то называется общей подпалиндромной подпоследовательностью (англ. common palindromic subsequence). Общая подпалиндромная последовательность, имеющая максимальную длину, называется наибольшей общей подпалиндромной подпоследовательностью (англ. The longest common palindromic subsequence (LCPS)) и мы обозначим её как .
Содержание
Наивное решение
Можно придумать такое решение данной задачи: найти наибольшую общую подпоследовательность, в ней найти наибольшую подпалиндромную подпоследовательность. Но, к сожалению, это решение неверно.
Контрпример
Возьмем 2 последовательности
и .Наибольшей общая подпоследовательность данных последовательностей равна
и в ней наибольшая подпалиндромная последовательность имеет длину .Но очевидно, что на самом деле последовательность
является наибольшим общей палиндромной подпоследовательностью и и имеет длину .Динамическое программирование
Заметим, что в качестве подзадач для
, в которых мы можем посчитать ответ, логично взять подпоследовательность от и от . Основываясь на этом наблюдении мы сформулируем следующую теорему, которая доказывает оптимальную подструктуру свойств задачи .Теорема: |
Пусть и - две последовательности длин и соответственно, а и — две подпоследовательности последовательностей и соответственно. Пусть - наибольшая общая подпалиндромная последовательность двух подпоследовательностей и . Тогда выполняются следующие утверждения,
|
На основании теоремы мы напишем следующую рекурсивную формулу для длины наибольшей общей подпалиндромной подпоследовательности:
Где
— длина наибольшей общей палиндромной подпоследовательности от и . Длина наибольшей общей палиндромной подпоследовательности от последовательностей и будет расположена в . Мы можем вычислить эту длину за время используя динамическое программирование.Реализация
Будем использовать динамику с запоминанием ответа. Оформим решения в виде рекурсивной функции
В массиве хранятся ответы для подзадач. До запуска функции заполним массив и будем использовать такую логику: мы имеем подзадачу , если , то значение для данной подзадачи мы еще не вычисляли и именно этим мы и займемся, иначе значение уже посчитано и мы можем просто вернуть . Так как каждое значение считается не более одного раза, мы получим асимптотику .
Псевдокод
int lcps (i: int, j: int, k: int, l: int) if (ans[i][j][k][l] // если так, то значение уже посчитано и нужно просто его вернуть 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 tmp = (2 + lcps(i + 1, j - 1, k + 1, l - 1)) return tmp ans[i][j][k][l] = tmp tmp = 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)) ans[i][j][k][l] = tmp return tmp-1)
См. также
- Динамическое программирование
- Задача о наибольшей общей подпоследовательности
- Задача о наибольшей подпоследовательности-палиндроме