49 lines
2.9 KiB
TeX
49 lines
2.9 KiB
TeX
\documentclass[10pt]{article}
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage{amsmath,amsthm,amssymb}
|
|
\usepackage{fullpage}
|
|
\usepackage{url}
|
|
\pagenumbering{gobble}
|
|
\usepackage{hyperref}
|
|
\usepackage{graphicx}
|
|
\input{statement/preamble.tex}
|
|
\title{ Tutorial: Maior Subsequência Palindrômica}
|
|
\author{Arthur Andrade D'Olival}
|
|
\date{}
|
|
\begin{document}
|
|
\maketitle
|
|
\section{Solução do Problema}
|
|
|
|
O problema de encontrar a Maior Subsequência Palindrômica (\textit{Longest Palindromic Subsequence} - LPS) pode ser resolvido de forma elegante utilizando \textbf{programação dinâmica em intervalos}. A ideia é analisar o problema de fora para dentro: comparamos os caracteres nas extremidades de uma substring e decidimos se eles farão parte do nosso palíndromo ou se devemos encolher o nosso intervalo de busca.
|
|
|
|
\subsection{Definição do Subproblema}
|
|
|
|
Seja $S$ a nossa string original de tamanho $N$, indexada de $0$ a $N-1$.
|
|
Definimos o nosso estado da programação dinâmica como:
|
|
|
|
$$dp[i][j] = \text{o comprimento da maior subsequência palindrômica dentro da substring } S[i \dots j].$$
|
|
|
|
Assim, a resposta para o comprimento máximo em toda a string será encontrada em $dp[0][N-1]$, que engloba o intervalo completo do primeiro ao último caractere.
|
|
|
|
\subsection{Função de Transição}
|
|
|
|
Para calcular $dp[i][j]$, olhamos para os caracteres nas pontas do intervalo atual: $S[i]$ e $S[j]$. Temos dois cenários possíveis:
|
|
|
|
1. \textbf{Os caracteres são iguais ($S[i] == S[j]$):} Eles podem formar as pontas de um palíndromo. Nesse caso, ganhamos $2$ de comprimento (um caractere de cada lado) e somamos ao melhor palíndromo que conseguimos formar no intervalo estritamente interno a eles.
|
|
$$dp[i][j] = dp[i+1][j-1] + 2$$
|
|
|
|
2. \textbf{Os caracteres são diferentes ($S[i] \neq S[j]$):} Como eles são diferentes, não podem formar as pontas do mesmo palíndromo simultaneamente. Precisamos descartar um dos lados e ver qual escolha nos dá o melhor resultado. Calculamos ignorando o caractere da esquerda (reduzindo para $i+1$) ou ignorando o da direita (reduzindo para $j-1$).
|
|
$$dp[i][j] = \max \big( dp[i+1][j], dp[i][j-1] \big)$$
|
|
|
|
\textit{Nota de implementação:} Para garantir que $dp[i+1][j-1]$ ou as outras dependências já estejam calculadas quando precisarmos delas, os laços devem processar os intervalos do menor para o maior, ou preenchendo o $i$ de trás para frente (de $N-1$ até $0$) e o $j$ de frente para trás (de $i+1$ até $N-1$).
|
|
|
|
\subsection{Casos Base}
|
|
|
|
Os casos base ocorrem para intervalos de tamanho 1 e intervalos inválidos (tamanho 0 ou negativo):
|
|
|
|
Todo caractere isolado é, por definição, um palíndromo de comprimento 1. Portanto, a diagonal principal da nossa matriz de estados recebe $1$:
|
|
$$dp[i][i] = 1 \quad \text{para todo } 0 \le i < N$$
|
|
|
|
Para intervalos onde o início ultrapassa o fim (o que pode ocorrer durante a transição de $dp[i+1][j-1]$ quando $j = i+1$), o comprimento é zero:
|
|
$$dp[i][j] = 0 \quad \text{para todo } i > j$$\end{document}
|