Módulo 10 - Memoização e a ideia da programação dinâmica

Memoização: anotar para não recalcular

8 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 12/07/2026

O que você vai aprender

  • Entender memoização como guardar e reusar resultados.
  • Ver a tabela (cache) sendo consultada antes de recalcular.
  • Perceber o ganho brutal de desempenho com uma mudança pequena.
  • Distinguir o custo de memória do ganho de tempo.

A ideia de anotar o que já foi feito

Imagine somar uma coluna comprida de números várias vezes ao longo do dia. Da primeira vez você soma tudo com cuidado; das próximas, se você anotou o total num canto do papel, é só ler a anotação. Memoização é exatamente isso, dentro do programa. A função ganha uma tabela ao lado, o cache, e passa a seguir um ritual novo: antes de calcular qualquer coisa, ela olha a tabela para ver se aquela resposta já está anotada. Se estiver, devolve na hora, sem trabalho. Se não estiver, calcula uma única vez, escreve o resultado na tabela e só então devolve. Nunca a mesma conta é feita duas vezes.

No Fibonacci, a chave da tabela é o número n e o valor é o fib de n já calculado. Da primeira vez que a função precisa de fib de 3, ela calcula e anota. Quando outro galho pedir fib de 3, a resposta já vai estar lá, pronta para ser lida. O galho que antes se abria numa subárvore inteira de recálculo agora encosta na tabela e volta na mesma hora. A árvore de recursão, que era gorda de repetições, murcha: cada valor é calculado uma vez só, e o resto é consulta.

Diagrama em duas partes. À esquerda, a árvore de recursão do Fibonacci gorda e cheia de nós repetidos, marcada como sem memoização. À direita, a mesma árvore bem menor: cada valor aparece uma vez só, calculado, e os pedidos seguintes apontam para uma tabela ao lado com as colunas n e fib de n preenchida (0 vale 0, 1 vale 1, 2 vale 1, 3 vale 2), marcada como com memoização. Setas dos nós repetidos vão direto para a tabela.
Com memoização, cada valor é calculado uma vez e guardado na tabela; os pedidos seguintes leem a resposta pronta.

O cache em ação

No pseudocódigo, o cache costuma ser um dicionário ou uma lista que sobrevive entre as chamadas. A função ganha duas linhas no começo e uma no fim. No começo: se o valor de n já está na tabela, retorne o que está lá. No fim: antes de retornar o resultado calculado, guarde-o na tabela sob a chave n. Só isso. A estrutura recursiva continua igual, o caso base continua igual, a soma dos dois anteriores continua igual. A diferença é que agora a função lembra. Repare que a lógica do cálculo não mudou; a gente só ensinou a função a não repetir trabalho.

tabela <- {}   // cache: chave n, valor fib(n)

funcao fib(n)
  se n <= 1 entao
    retorne n
  fim
  se tabela tem a chave n entao
    retorne tabela[n]   // resposta pronta, sem recalcular
  fim
  resultado <- fib(n - 1) + fib(n - 2)
  tabela[n] <- resultado   // anota antes de devolver
  retorne resultado
fim

Duas linhas extras (consultar e anotar) transformam o desempenho, sem mudar a lógica do cálculo.

🎮 Jogo da aula

Verdadeiro ou falso sobre memoização

Decida se cada afirmação sobre memoização é verdadeira ou falsa.

O preço da memória

Não existe almoço grátis, e a memoização cobra o preço dela em memória. A tabela precisa guardar um resultado para cada entrada diferente que aparecer. No Fibonacci, isso é pouca coisa: uma entrada por número até n. Mas em problemas com muitas combinações de entrada, a tabela pode crescer bastante, e aí você troca um problema de tempo por um de espaço. Na prática, quase sempre vale a pena, porque tempo costuma ser o recurso mais escasso e a repetição costuma ser gigante. Ainda assim, é bom ter consciência de que o cache mora em algum lugar e ocupa espaço.

Teste rápido

O que a função memoizada faz ANTES de calcular fib de n?

Perguntas frequentes

De onde vem a palavra memoização?
Vem de memorando, uma nota, um lembrete. A ideia é que a função passa a anotar o que já calculou, como quem escreve um recado para si mesma. Não confunda com memorização no sentido de decorar; aqui é a função que guarda resultados numa tabela para não refazer contas.
Qual a diferença entre memoização e cache?
São muito próximos. Cache é o nome geral de uma memória onde se guardam resultados para reusar. Memoização é o uso específico dessa ideia dentro de uma função, guardando o resultado de cada cálculo pela sua entrada. Toda memoização usa um cache; nem todo cache é memoização.
A memoização muda o resultado do cálculo?
Não. O resultado é exatamente o mesmo; só o caminho até ele fica mais curto. A lógica, o caso base e a fórmula continuam iguais. As únicas mudanças são consultar a tabela antes de calcular e gravar o resultado depois. Por isso ela acelera sem introduzir erro.
Ela funciona com qualquer função recursiva?
Só compensa quando há repetição de subproblemas e quando a mesma entrada dá sempre o mesmo resultado. Se cada chamada resolve um pedaço novo (sem repetição) ou se a resposta pode mudar, a tabela não ajuda ou até atrapalha. O Fibonacci é o caso perfeito porque tem muita repetição e é determinístico.
Quanto de memória a tabela consome?
Uma entrada para cada valor diferente que aparecer. No Fibonacci é pouca coisa, uma por número até n. Em problemas com muitas combinações de entrada, o cache pode crescer bastante, e você acaba trocando um custo de tempo por um de espaço. Na maioria dos casos, essa troca compensa.
As linguagens já trazem memoização pronta?
Muitas têm um jeito rápido de ligar um cache numa função sem escrever a tabela na mão, como um enfeite que se coloca em cima dela. Por baixo, o mecanismo é o mesmo desta aula: guardar o resultado por entrada e reusar. Entender o pseudocódigo ajuda a saber o que esses atalhos fazem de verdade.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.