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

Recalcular à toa: o Fibonacci ingênuo

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

Velocidade

O que você vai aprender

  • Entender a definição recursiva do Fibonacci.
  • Ver por que a versão ingênua recalcula os mesmos valores.
  • Enxergar o desperdício na árvore de recursão.
  • Perceber por que o custo explode com números maiores.

A definição que engana

O Fibonacci é o exemplo que todo mundo usa para mostrar recursão, e com razão: a definição é linda de tão simples. Os dois primeiros números são dados, 0 e 1. Daí em diante, cada número é a soma dos dois que vêm antes dele. Escrever isso como função recursiva sai quase sozinho: se n é 0 ou 1, devolva o próprio n; senão, devolva fib de n menos 1 somado com fib de n menos 2. Três linhas, um caso base claro, duas chamadas que reduzem o problema. Pelo que você viu no módulo de recursão, parece o cenário ideal. E é aí que mora a armadilha.

O problema não está na resposta, que sai correta, mas no caminho até ela. Para calcular fib de 5, a função pede fib de 4 e fib de 3. Mas fib de 4, por sua vez, também pede fib de 3. Então fib de 3 é calculado duas vezes, do zero, por galhos diferentes que não conversam entre si. E fib de 2 aparece ainda mais vezes. Quanto maior o número, pior fica: a mesma conta é refeita uma montanha de vezes. A árvore de recursão, que no módulo passado mostrava o trabalho total, aqui denuncia um trabalho quase todo desperdiçado.

Árvore de recursão do cálculo de fib de 5. No topo, fib de 5 se abre em fib de 4 e fib de 3. Cada um se abre de novo, e a árvore desce cheia de repetições. Os nós fib de 3, fib de 2, fib de 1 e fib de 0 aparecem destacados em várias posições, com um contador ao lado mostrando quantas vezes cada um é recalculado, deixando visível que os mesmos valores são refeitos várias vezes.
A árvore de fib de 5 mostra o desperdício: os mesmos valores (fib de 3, fib de 2) aparecem recalculados em galhos diferentes.

O desperdício em números

Dá para medir o estrago contando quantas vezes a função é chamada. Para fib de 5, a função ingênua faz quinze chamadas para achar um número que a gente calcula de cabeça. Para fib de 10, são mais de cem chamadas. Para fib de 30, são mais de um milhão. Para fib de 50, o número de chamadas passa de um bilhão, e o programa simplesmente trava. Repare que o valor final é pequeno e a definição é simples; o que explode é a quantidade de trabalho repetido. Cada valor intermediário é redescoberto vezes e vezes, porque nada é guardado entre uma chamada e outra.

funcao fib(n)
  se n <= 1 entao
    retorne n
  fim
  retorne fib(n - 1) + fib(n - 2)
fim

// para achar fib(5), esta funcao chama fib(3) duas vezes,
// fib(2) tres vezes, fib(1) cinco vezes... tudo do zero.
escreva(fib(6))

A função está correta, mas cada chamada abre duas novas, e valores como fib de 2 são recalculados várias vezes.

🎮 Jogo da aula

Qual Fibonacci sai?

Siga a definição (cada número é a soma dos dois anteriores) e descubra o valor que o programa mostra.

funcao fib(n)
  se n <= 1 entao
    retorne n
  fim
  retorne fib(n - 1) + fib(n - 2)
fim
escreva(fib(6))

O mesmo trabalho, de novo e de novo

Vale fixar a intuição, porque ela é a chave das próximas aulas. O Fibonacci ingênuo é lento não por causa da recursão em si, mas por causa da amnésia: a função esquece na hora tudo o que acabou de calcular. Cada vez que precisa de fib de 3, ela recomeça do zero, como quem soma a mesma coluna de números várias vezes sem anotar o resultado no papel. A cura, que vem na próxima aula, é ridícula de tão simples: anotar. Se a função guardasse cada resultado que já achou, nunca precisaria refazer, e o cálculo passaria de bilhões de passos para umas poucas dezenas.

Teste rápido

Por que o cálculo de fib de 5 pela função recursiva ingênua faz tanto trabalho repetido?

Perguntas frequentes

A recursão do Fibonacci está errada, então?
Não, ela está certa: devolve o valor correto. O problema é o desempenho. Ela recalcula os mesmos pedaços muitas vezes porque não guarda resultado nenhum entre as chamadas. Uma solução pode estar logicamente correta e ainda ser inviável na prática por ser lenta demais, e este é o caso clássico disso.
Por que fib de 3 é calculado mais de uma vez?
Porque ele é pedido por galhos diferentes da árvore de recursão. Para achar fib de 5, a função pede fib de 4 e fib de 3. E fib de 4 também precisa de fib de 3. Como os dois galhos não conversam, cada um calcula fib de 3 do zero. Quanto maior o número, mais essa repetição se multiplica.
O custo cresce quão rápido?
Muito rápido. Fib de 10 já passa de cem chamadas, fib de 30 passa de um milhão e fib de 50 passa de um bilhão, ao ponto de travar o programa. O valor final continua pequeno; o que explode é a quantidade de trabalho repetido. Esse crescimento acelerado é o que torna a versão ingênua impraticável.
Dá para consertar sem abandonar a recursão?
Dá, e essa é a graça da próxima aula. Basta a função guardar cada resultado que já achou numa tabela e consultar essa tabela antes de recalcular. A recursão continua, mas a amnésia acaba. Com essa mudança pequena, o cálculo passa de bilhões de passos para umas poucas dezenas.
Esse problema aparece só no Fibonacci?
Não. O Fibonacci é o exemplo mais didático, mas o mesmo desperdício aparece sempre que uma recursão redescobre os mesmos subproblemas. Contar caminhos numa grade, o problema do troco e a subida de uma escada por degraus têm exatamente esse padrão. Reconhecer a repetição é o primeiro passo para curá-la.
Contar chamadas é uma boa forma de medir custo?
É uma forma bem concreta e intuitiva. Cada chamada faz um pouco de trabalho, então o número de chamadas é uma boa medida de quanto esforço o programa gasta. Ver esse número saltar de quinze para um bilhão deixa o desperdício palpável, sem precisar de fórmulas complicadas de análise de custo.

Fontes

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