50 lines
3.1 KiB
TeX
50 lines
3.1 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 Crescente}
|
|
\author{Arthur Andrade D'Olival}
|
|
\date{}
|
|
\begin{document}
|
|
\maketitle
|
|
\section{Solução do Problema}
|
|
|
|
O problema de encontrar a maior subsequência crescente (\textit{Longest Increasing Subsequence} - LIS) é um clássico que pode ser resolvido de forma eficiente por meio de \textbf{programação dinâmica}. A ideia central é focar no final da subsequência: para cada elemento da sequência original, calculamos qual é a maior subsequência crescente que termina exatamente nele.
|
|
|
|
\subsection{Definição do Subproblema}
|
|
|
|
Seja $a$ o nosso vetor de números inteiros com $N$ elementos, indexado de $0$ a $N-1$.
|
|
Definimos o nosso estado da programação dinâmica como:
|
|
|
|
$$d[i] = \text{o comprimento da maior subsequência crescente que termina obrigatoriamente no índice } i.$$
|
|
|
|
A resposta final para o tamanho da maior subsequência não será necessariamente $d[N-1]$, mas sim o maior valor alcançado em todo o vetor $d$, ou seja, $\max(d[i])$ para $0 \le i < N$.
|
|
|
|
\subsection{Função de Transição}
|
|
|
|
Para determinar o valor de $d[i]$, precisamos olhar para todos os elementos anteriores à posição $i$, ou seja, um índice $j$ tal que $0 \le j < i$.
|
|
|
|
Se encontrarmos um elemento anterior que seja estritamente menor que o elemento atual ($a[j] < a[i]$), isso significa que podemos estender a subsequência que terminava em $j$ anexando o elemento $a[i]$ ao final dela. O novo comprimento seria $d[j] + 1$.
|
|
Avaliamos todos os possíveis índices $j$ válidos e mantemos o que gera o maior comprimento:
|
|
|
|
$$d[i] = \max_{\substack{0 \le j < i \\ a[j] < a[i]}} \big( d[j] + 1 \big)$$
|
|
|
|
\subsection{Casos Base}
|
|
|
|
O caso base é bastante intuitivo: na pior das hipóteses, qualquer elemento isolado forma, por si só, uma subsequência válida de comprimento $1$. Portanto, a nossa inicialização padrão para todos os estados é:
|
|
|
|
$$d[i] = 1 \quad \text{para todo } 0 \le i < N$$
|
|
|
|
\subsection{Recuperação da Decomposição (Elementos da subsequência)}
|
|
|
|
Como o problema exige a impressão dos elementos que formam a subsequência, precisamos reconstruir o caminho ótimo. Para isso, utilizamos um vetor auxiliar $p[i]$ (de \textit{parent} ou predecessor), inicializado com $-1$.
|
|
|
|
Durante a transição, sempre que atualizamos $d[i]$ com um valor maior proveniente de um $d[j] + 1$, registramos o índice de origem definindo $p[i] = j$.
|
|
|
|
Após calcularmos todo o vetor $d$, localizamos o índice \texttt{pos} que contém o valor máximo absoluto de $d$. A partir de \texttt{pos}, recuperamos os elementos da subsequência percorrendo o caminho reverso: adicionamos $a[\texttt{pos}]$ à nossa lista de resposta e saltamos para o predecessor atualizando $\texttt{pos} = p[\texttt{pos}]$. Repetimos o processo até que $\texttt{pos}$ seja $-1$. Como resgatamos os elementos do final para o começo, basta inverter a lista resultante para apresentar a subsequência na ordem crescente original.\end{document}
|