O que já calculamos pode responder a uma decisão nova?
stage / DP
passo 01 / 05baseestado / base
001
002
003
004
005
006
estado 0↗estado 1↗reuso
foco atual / inicializar o estadoa faixa mostra o estado, não uma medição de tempo real
ação / progresso comparação / estado conflito / limite
telemetria / estratégia
passo01inicializar o estado
estadobaseestado observado
códigolinha 1JavaScript
estadopausadocontrole manual
/ o que está acontecendo
inicializar o estado reutilize a evidência.
Antes de considerar itens, a capacidade vazia tem valor zero. Esse caso base ancora as próximas transições.
→
princípio / Subestrutura ótima e subproblemas sobrepostos permitem guardar respostas parciais e reutilizá-las.
limite que não pode ser omitido Dynamic Programming não é apenas usar uma tabela. É necessário definir um estado que represente o problema e uma transição que preserve a resposta correta.
complexidade / mapa rápido
melhorO(n·C)
médioO(n·C)
piorO(n·C)
Aqui, n é o número de itens e C representa a capacidade discreta da mochila visualizada.
Como ler esta réguaEla não mede o tempo do seu aparelho: compara o crescimento quando aumentam os itens, os estados possíveis ou as decisões de uma estratégia.
operações
O(n·C) · Grade de estados
Há dois eixos: n é o número de itens e C é a capacidade ou quantidade de estados possíveis. O algoritmo avalia combinações desses dois limites.
Aumentar apenas n ou apenas C aumenta o trabalho; aumentar os dois multiplica a quantidade de estados examinados.
comparação / duas técnicas
Compare o crescimento lado a lado
Escolha duas técnicas diferentes. As curvas usam a mesma escala visual para explicar como o custo tende a aumentar.
Use este par para contrastar uma escolha local eficiente com o custo de preencher e reutilizar estados em problemas de capacidade. Greedy Algorithm e Dynamic Programming usam parâmetros diferentes: O(n·C) depende da capacidade C, e O(bᵈ) depende da ramificação b e da profundidade d. A régua contrasta modelos de crescimento; só compare a inclinação sob hipóteses explícitas sobre como esses parâmetros aumentam.
/ por baixo do palco
Uma memória, um estado.
O destaque acompanha a decisão atual. Leia o pseudocódigo antes de trocar de linguagem; a implementação é uma tradução, não um novo algoritmo.
01tabela[0][capacidade] ← 0
02para cada item:
03 para capacidade decrescente:
04 sem_item ← tabela anterior
05 com_item ← valor + estado restante
06 tabela ← máximo dos dois
implementação / JavaScript
01const table = Array(capacity + 1).fill(0); // Initialize one state for each capacity02for (const item of items) {03 for (let limit = capacity; limit >= item.weight; limit--) {04 table[limit] = Math.max(table[limit],05 table[limit - item.weight] + item.value06 );07 }08}09return table[capacity];
/ leitura técnica · estados reutilizáveis
Guardar resultado não basta: guarde o estado certo.
Dynamic Programming formula uma família de subproblemas, registra o valor de cada estado e reutiliza esse resultado quando a mesma situação reaparece. A tabela não é a estratégia; ela é apenas uma forma de materializar uma recorrência que já precisa estar bem definida.
01 / estado
Resuma o passado que altera o futuro.
Um estado deve reter apenas a informação necessária para decidir o restante. Em Knapsack 0/1, item considerado e capacidade residual importam; em LCS, os dois prefixos importam. Omissões tornam a transição incorreta.
02 / transição
Enumere as decisões válidas.
A recorrência transforma respostas menores em uma resposta atual. Ela precisa cobrir todas as alternativas permitidas — por exemplo, incluir ou excluir um item — e combinar seus valores de acordo com o objetivo de minimizar, maximizar ou contar.
03 / ordem
Calcule dependências antes de consultá-las.
Casos-base corretos e uma ordem de avaliação válida sustentam a prova por indução. Em uma tabela, cada consulta deve apontar para um estado já calculado; em memoização, a chamada recursiva preenche a dependência sob demanda.
invariante / leitura da bancada
A faixa colorida representa valores armazenados para estados menores. Ela mostra reuso, não uma prova automática de optimalidade: a garantia depende de o estado distinguir todos os futuros relevantes e de a transição preservar o valor correto para cada célula.
/ contrato que precede a tabela
Um estado é uma pergunta, não uma posição visual.
Antes de escrever loops, declare a unidade de progresso, o valor procurado, as decisões que levam a ele e a informação que modifica essas decisões. Essa disciplina separa Dynamic Programming de uma matriz preenchida por tentativa e erro.
BASEO menor estado já tem respostaAncora a indução e encerra dependências.
VALORO que o estado medeCusto mínimo, ganho máximo, contagem ou probabilidade.
TRANSIÇÃOComo alternativas válidas se combinamDeve cobrir as escolhas permitidas no estado atual.
PREDECESSORQual decisão produziu o valorNecessário quando se deseja reconstruir uma solução, não só seu valor.
Memoização e tabulação devem devolver o mesmo valor quando partem da mesma recorrência correta. A escolha entre elas altera quais estados são visitados, o uso da pilha, a facilidade de depuração e a forma de reconstruir decisões — não o problema matemático resolvido.
ASPECTOMEMOIZAÇÃOTABULAÇÃO
Ordemrecursiva, guiada pela consultaiterativa, definida antes do preenchimento
Estadoscalcula os alcançados pela demandaem geral percorre toda a região planejada
Pilhausa chamadas; profundidade pode importarevita profundidade recursiva
Risco comumcache ou caso-base incompletoordem que lê uma célula ainda não pronta
custo / conte estados e transições
Não confunda polinomial com pseudo-polinomial.
Uma estimativa útil é número de estados alcançados × custo por transição. Na mochila com capacidade C, o custo O(n·C) depende do valor numérico de C; portanto, é pseudo-polinomial quando C chega codificado em binário. O espaço inclui a tabela, o cache e, se necessário, predecessores para reconstrução.
/ decisão de uso
Reutilize estados; não decisões prematuras.
Use Dynamic Programming quando subproblemas se sobrepõem e a recorrência possui subestrutura ótima. Prefira Divide and Conquer quando as chamadas são independentes; prefira Greedy apenas quando houver uma escolha local segura provada. Documente a dimensão do estado, a ordem de preenchimento, o custo de memória e se a compressão de espaço ainda permite reconstruir a solução desejada.