chore: build all pdfs

This commit is contained in:
2026-04-07 23:12:21 -03:00
parent 47a0a1f3cf
commit dff7fc9018
58 changed files with 224 additions and 59 deletions

View File

@@ -0,0 +1,52 @@
\documentclass[10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{fullpage}
\usepackage{url}
\pagenumbering{gobble}
\usepackage{hyperref}
\title{ Tutorial: Estouro}
\author{Leetcode 312}
\date{}
\begin{document}
\maketitle
\section{Solução do Problema}
O problema de maximizar a energia ao estourar balões pode ser resolvido de forma eficiente por meio de \textbf{programação dinâmica em intervalos}. A grande sacada para modelar este problema é pensar no processo de trás para frente: em vez de tentar adivinhar qual balão estourar primeiro, o que muda constantemente os vizinhos dos balões restantes, escolhemos qual será o \textbf{último balão} a ser estourado em um determinado subintervalo.
Para lidar com as bordas da fileira sem precisar de múltiplos \texttt{if}s, adicionamos balões virtuais com valor $1$ nas extremidades.
\subsection{Definição do Subproblema}
Seja a nossa fileira de balões original de tamanho $N$. Criamos um novo vetor $B$ de tamanho $N+2$, onde $B[0] = 1$, $B[N+1] = 1$, e as posições de $1$ a $N$ recebem os valores fornecidos.
Definimos o nosso estado da programação dinâmica como:
$$dp[i][j] = \text{a quantidade máxima de energia obtida ao estourar todos os balões no intervalo } [i, j].$$
Assim, $dp[1][N]$ representará a nossa resposta ótima, correspondente ao intervalo que engloba todos os balões reais.
\subsection{Função de Transição}
Para calcular $dp[i][j]$, vamos iterar por um pivô $k$ (com $i \le k \le j$) que representa o \textbf{último balão} a ser estourado dentro desse subintervalo.
Como $k$ é o último a sobreviver entre $i$ e $j$, todos os outros balões internos já foram estourados. Consequentemente, no exato momento da explosão de $k$, seus vizinhos diretos garantidamente serão $B[i-1]$ e $B[j+1]$. A energia liberada por esse estopim final será $B[i-1] \times B[k] \times B[j+1]$.
O valor total do intervalo será a soma da energia desse balão $k$ com as energias máximas dos subproblemas que o antecederam na ordem cronológica de explosão: o intervalo à esquerda ($i$ até $k-1$) e o intervalo à direita ($k+1$ até $j$). Portanto:
$$dp[i][j] = \max_{i \le k \le j} \big( dp[i][k-1] + B[i-1] \cdot B[k] \cdot B[j+1] + dp[k+1][j] \big)$$
\subsection{Casos Base}
Os casos base da nossa recursão (ou inicialização da matriz) ocorrem para intervalos vazios, ou seja, quando o índice de início ultrapassa o índice de fim ($i > j$). Nesses casos, como não há balões para estourar, a energia liberada é naturalmante nula:
$$dp[i][j] = 0 \quad \text{para todo } i > j$$
Como a implementação iterativa inicializa a matriz completa com zeros, essa condição já é suprida por padrão.
\subsection{Recuperação da Decomposição (Ordem das explosões)}
Para além da energia máxima $dp[1][N]$, frequentemente queremos também a sequência de explosões que atinge esse valor. Para isso, mantemos uma matriz auxiliar \texttt{cut[i][j]} durante a computação, que armazena o índice $k$ responsável pelo maior ganho em $dp[i][j]$.
Após preencher $dp$ e \texttt{cut}, criamos uma função recursiva para reconstruir a resposta. Ao chamarmos a função para o intervalo $[1, N]$, descobrimos o pivô $k = \texttt{cut}[1][N]$. Sabemos que $k$ é o \textit{último} balão estourado. Em seguida, chamamos recursivamente para os subintervalos $[1, k-1]$ e $[k+1, N]$. Ao empilharmos esses balões, obtemos a sequência cronológica invertida; basta inverter a lista no final para obtermos a sequência exata das explosões.\end{document}