📘 CodingMarble Learn

Técnicas de Projeto de Algoritmos

Para projetar um algoritmo, primeiro especifique o problema: os dados de entrada, a saída esperada e as condições. Depois escreva passos claros e finitos, em linguagem natural, em lista, em pseudocódigo ou em fluxograma. Problemas grandes são divididos de cima para baixo em partes menores (refinamento por etapas) ou construídos de baixo para cima a partir de pequenas peças já testadas. Técnicas clássicas: força bruta (testar tudo), dividir e conquistar (dividir, resolver e combinar; dividir ao meio, como na busca binária e no merge sort), guloso (pegar a melhor escolha do momento; rápido, mas nem sempre ótimo), programação dinâmica (resolver cada subproblema uma só vez e guardar numa tabela) e backtracking (tentar uma escolha e desfazer num beco sem saída). Escolha a técnica e as estruturas de dados (vetores, pilhas, árvores binárias) verificando a correção e a eficiência (complexidade de tempo).

🎬 História passo a passo

  1. Primeiro, especifique o problema. Entrada: 8 números. Saída: o maior. Passos: olhe cada caixa e guarde o maior até agora.
  2. Dividir e conquistar: para achar um número de 1 a 16, pergunte pelo meio e jogue metade fora. Bastam 4 perguntas.
  3. Guloso: pegue sempre a maior moeda que cabe. É rápido, mas para 6 com moedas 1, 3, 4 dá 3 moedas, e não as 2 melhores.
  4. Programação dinâmica: resolva primeiro os valores pequenos e guarde cada resposta numa tabela. A tabela encontra 6 = 3 + 3.
  5. Backtracking: siga um caminho; num beco sem saída, volte à última escolha e tente outro jeito, até chegar à saída.
  6. Sua vez: escolha um valor e as moedas. Preveja: o guloso dá o menor número de moedas? Compare com a PD.

Dica: arraste a cena 3D para girar. Use dois dedos para dar zoom.

🤔 Dúvidas comuns, esclarecidas

Por que escrever entrada e saída antes de programar?

Se você não sabe exatamente o que entra e o que deve sair, não consegue testar se os passos estão certos.

Como 4 perguntas bastam para 16 números?

Cada resposta joga metade fora: 16, 8, 4, 2, 1. As caixas cinza mostram a metade removida.

Se o guloso pode errar, por que usá-lo?

Ele é muito rápido e simples e, para muitos problemas (moedas normais, atividades que terminam mais cedo), está provado que é correto.

Em que a PD é diferente de testar tudo?

Ela resolve cada valor pequeno uma vez e o reutiliza, então a tabela cresce passo a passo em vez de explorar todas as combinações.

O backtracking recomeça do início?

Não. Ele volta só até o último cruzamento que ainda tem um caminho não testado e segue dali.

Como sei se o guloso funciona para as minhas moedas?

Compare-o com a PD para muitos valores. Teste as moedas 1, 7, 10 no modo livre.

Especificar um problema: entrada, saída e passos

Antes de escrever qualquer código, descreva o problema com exatidão. Isso é a especificação.

Escrever os passos

Um algoritmo é uma lista finita de passos claros que transforma qualquer entrada válida na saída certa. Escreva-o como:

Teste à mão com entradas pequenas, inclusive as difíceis (todos iguais, números negativos, um único número).

Projeto top-down e bottom-up

Top-down (de cima para baixo, refinamento por etapas): comece com a tarefa inteira, divida-a em poucos passos grandes e divida cada passo de novo, até que cada parte seja fácil de programar. Exemplo: "Fazer um boletim" → ler as notas → calcular as médias → dar os conceitos → imprimir.

Bottom-up (de baixo para cima): construa e teste primeiro peças pequenas e reutilizáveis (uma função que acha o máximo, outra que ordena) e depois junte tudo no programa completo.

Projetos reais misturam os dois: planeje de cima para baixo, construa e teste de baixo para cima.

Dividir e conquistar e o método da divisão ao meio

Dividir e conquistar tem três movimentos: dividir o problema em partes menores do mesmo tipo, resolver cada parte (muitas vezes por recursão) e combinar as respostas.

Algoritmos gulosos

Um algoritmo guloso faz a escolha que parece melhor agora e nunca a muda.

Mas o guloso nem sempre acerta: com moedas 1, 3, 4, pagar 6 de forma gulosa dá 4 + 1 + 1 (3 moedas), enquanto 3 + 3 usa 2. Para confiar num método guloso, você precisa prová-lo ou testá-lo contra um método seguro.

Programação dinâmica e backtracking

Programação dinâmica (PD)

Quando os mesmos problemas menores se repetem, resolva cada um uma só vez e guarde a resposta numa tabela. Menor número de moedas para o valor a: best[a] = 1 + min(best[a - c]) sobre as moedas c ≤ a, começando com best[0] = 0. Para as moedas 1, 3, 4: best = 0, 1, 2, 1, 1, 2, 2. Preencher a tabela do pequeno para o grande é bottom-up; a recursão com memória é top-down (memoização). Veja a lição separada de Programação dinâmica para saber mais.

Backtracking

Monte uma solução uma escolha por vez. Se uma escolha quebra uma regra ou leva a um beco sem saída, desfaça-a e tente a próxima opção. É usado em labirintos, Sudoku, no problema das N rainhas e para listar todos os subconjuntos. É uma força bruta cuidadosa: pula ramos inteiros que não podem funcionar.

Força bruta

Teste todas as respostas possíveis. Está sempre correta, mas muitas vezes é lenta demais (2ⁿ subconjuntos, n! ordens).

Escolher uma técnica: correção, eficiência e estruturas de dados

TécnicaUse quandoExemploTempo típico
Força brutaa entrada é minúsculatestar todas as senhas de 3 dígitosmuitas vezes 2ⁿ ou n!
Dividir e conquistaras partes são independentesbusca binária, merge sortO(log n), O(n log n)
Gulosouma boa escolha local é comprovadamente seguraseleção de atividades, trocoO(n log n)
Programação dinâmicaos subproblemas se repetemtroco, caminhos mais curtostamanho da tabela
Backtrackingbusca com regraslabirinto, Sudokuexponencial, mas com poda

Justifique

Correção: mostre que o algoritmo sempre para e dá a saída certa (um invariante de laço, uma prova ou testes em casos extremos). Eficiência: conte os passos conforme n cresce (notação O) e compare com outros métodos.

As estruturas de dados ajudam

Vetores para tabelas (PD), pilhas para backtracking (lembrar para onde voltar), filas para busca nível por nível. Uma árvore binária guarda itens de modo que cada nó tem no máximo dois filhos; numa árvore binária de busca, as chaves menores vão para a esquerda e as maiores para a direita, então a busca corta o trabalho pela metade a cada nível, como na busca binária.

Experimente: moedas e um jogo de adivinhação

  1. Jogue o jogo de adivinhar de 1 a 100 com um amigo. Pergunte sempre pelo meio. Você sempre consegue ganhar em 7 perguntas? (2⁷ = 128.)
  2. Com as moedas 1, 3, 4, escreva no papel a tabela de PD para os valores de 0 a 10. Onde o guloso falha?
  3. Abra o último passo em 3D. Teste as moedas 1, 7, 10 e o valor 14. O guloso dá 10 + 1 + 1 + 1 + 1; a PD dá 7 + 7.
  4. Escreva uma lista de passos para "achar o menor número de uma lista" e teste com 5, 5, 5 e com um único número.

Fórmulas e definições principais

Exemplos resolvidos

1. Escreva uma especificação e uma lista de passos para achar o maior de n números.

Entrada: n ≥ 1 números. Saída: o maior. Passos: 1. melhor ← primeiro número. 2. Para cada outro número x: se x > melhor, melhor ← x. 3. Mostre melhor. Para 4, 9, 2, 7, 12, 5, 10, 3 a saída é 12, depois de 7 comparações.

2. Quantas perguntas a divisão ao meio precisa para achar um número de 1 a 1000?

Cada pergunta divide o intervalo ao meio: 1000 → 500 → 250 → 125 → 63 → 32 → 16 → 8 → 4 → 2 → 1. São 10 perguntas (2¹⁰ = 1024 ≥ 1000).

3. Pague 87 de forma gulosa com as moedas 50, 20, 10, 5, 2, 1.

50 (restam 37), 20 (17), 10 (7), 5 (2), 2 (0): 50 + 20 + 10 + 5 + 2 = 5 moedas.

4. Preencha a tabela de PD para as moedas 1, 3, 4 até o valor 7.

best[0]=0, [1]=1, [2]=2, [3]=1, [4]=1, [5]=min(best4, best2, best1)+1=2, [6]=min(best5, best3, best2)+1=2, [7]=min(best6, best4, best3)+1=2 (3 + 4).

5. Atividades (início-fim): A 9-11, B 10-12, C 11-13, D 12-14, E 13-15. Escolha o maior número de atividades que não se sobrepõem.

Guloso pelo término mais cedo: A (termina às 11), depois C (começa às 11, termina às 13), depois E (começa às 13). 3 atividades: A, C, E.

6. Planeje de cima para baixo: um programa que diz à turma a nota média e o melhor aluno.

Nível 1: ler os dados → calcular → imprimir. Nível 2: ler nomes e notas em listas; calcular o total e a média; achar a maior nota e o nome dela; imprimir os dois. Depois cada parte é programada e testada de baixo para cima.

Erros comuns

Quiz de prática

1. A especificação de um problema deve dizer:
2. A busca binária em 16 itens ordenados precisa, no máximo, de cerca de:
3. Qual técnica sempre pega a escolha que parece melhor agora?
4. A programação dinâmica funciona bem quando:
5. Numa busca em labirinto, voltar ao último cruzamento depois de um beco sem saída é:

Prática: responda você mesmo

Digite ou escolha sua resposta e aperte Conferir. Use a dica se travar; a solução completa aparece depois que você responder.

Perguntas frequentes

Quais são as principais técnicas de projeto de algoritmos?

Força bruta, dividir e conquistar, guloso, programação dinâmica e backtracking, escolhidas depois de especificar a entrada e a saída.

Qual é a diferença entre guloso e programação dinâmica?

O guloso faz uma escolha que parece a melhor em cada passo e nunca olha para trás. A PD considera todas as escolhas para os subproblemas pequenos e guarda as melhores respostas, então encontra o ótimo verdadeiro quando os subproblemas se sobrepõem.

O que é projeto top-down e bottom-up?

O top-down divide a tarefa inteira em passos menores; o bottom-up constrói e testa primeiro as partes pequenas e depois as junta. A maioria dos programas usa os dois.

Onde isso é ensinado

PolandSzkoła podstawowa, klasa VIIUnderstanding, analysing and solving problems
PolandSzkoła podstawowa, klasa VIIIUnderstanding, analysing and solving problems
PolandLiceum ogólnokształcące, klasa IUnderstanding, analysing and solving problems
China高三Electives (选修)

Aprenda antes

Aprenda depois

Aulas relacionadas

Todas as aulas de Computer Science