Você está na página 1de 40

MARCOS GUILHERME CASSOLATO DE OLIVEIRA

FACULDADE CAMPO LIMPO PAULISTA


MESTRADO EM CIÊNCIA DA
COMPUTAÇÃO

Complexidade de
Algoritmos
Lista de Exercícios
1

Prof. Osvaldo.

1. Descreva alguns problemas associados ao emprego de metodologias de análise de


algoritmos baseadas em experimentação?

(1) Impossibilidade de conclusão da análise – Pode não ser possível concluir a


análise diante de algoritmos que envolvam longos e/ou intermináveis ciclos de
iteração. Até mesmo algoritmos tecnicamente simples podem, em alguns casos,
demandar tempo de execução inviável ainda que computados pelas mais velozes
máquinas já produzidas pelo homem.

(2) Imprevisibilidade do comportamento assintótico – A análise experimental pode


não sugerir o real comportamento assintótico de um algoritmo; isto é, sua
tendência para tamanhos de entrada suficientemente grandes. A amostra tomada
para um determinado experimento pode ser capaz de concluir a eficácia de um
algoritmo, ao passo que oculta sua ineficiência, pois, se analisado sob valores de
entrada maiores, talvez demandasse tempo de execução expressivamente
superior àqueles observados por amostragem.

(3) Esforço de implementação – A análise experimental requer um esforço de


implementação do algoritmo, potencialmente superior ao esforço necessário
para sua análise formal (teórica). Desde uma simples tabela de simulações à
implementação efetiva do algoritmo numa linguagem de programação qualquer,
seja como for, a análise experimental implica esforço.

(4) Exposição a erros – O empirismo na análise de algoritmos, sobretudo se


executado humanamente, expõe-nos a erros. Dentre estes, erros associados à
precisão numérica, não aleatoriedade de número pseudo-aleatórios, medição
imprecisa e até erros de implementação.

(5) Sujeição às variações ambientais – enquanto que na análise teórica podemos


assumir uma máquina de desempenho constante, na análise experimental
estamos sujeitos às eventuais variações de resultados conforme a máquina que
executa, ou mesmo conforme as condições ambientais de uma mesma máquina.
2. Calcule o k-ésimo (k indicado em cada caso) termo de cada uma das sequências
abaixo:

a) 1, 2, 3, 4, ... (k = 10).
( )

b) 2, 4, 6, 8, ... (k = 20).
( )

c) 3, 6, 9, 12, ... (k = 15).


( )

d) 1, 2, 4, 8, 16, … (k = 10).

e) 81, 27, 9, 3, 1, … (k = 6).

( *

3. Quantos termos possuem cada uma das sequências abaixo e qual é a soma dos seus
termos?

Quantidade de termos Soma dos termos


PA ( ) ( )

PG ( )

( *

a) 1, 2, 3, 4, ..., 10.

( )

( )
b) 2, 4, 6, 8, ..., 2n, onde n ≥ 1
( )

( )

c) 2, 4, 8, 16, ..., 1024.


( * ( )

( )

d) 1, 2, 4, 8, 16, ..., 2n, onde n ≥1


( *

( )

e) 3n, ..., 27, 9, 3, 1.

( * ( )

( ) ( )

4. Diga, para cada caso, quantas vezes o comando fictício “S” será executado. Assuma
que “S” não altera o valor da variável de controle dos laços.

a)
para i := 1 até 2*n faça R: 𝟐𝒏 vezes, p/ 𝒏 ≥ 𝟏
S;

b)
para i := 1 até n2 faça R: 𝒏𝟐 vezes, p/ 𝒏 ≥ 𝟏
S;

c)
para i := 1 até n faça 𝑛 (𝑛 )
para j := 1 até i
faça
S;
𝒏𝟐 𝒏
R: 𝟐
vezes, p/ 𝒏 ≥ 𝟏
d)
para i := 1 até 2*n faça 𝑛 ( 𝑛 ) 𝑛 𝑛
para j := 1 até i →
faça
S;
R: 𝟐𝒏𝟐 𝒏 vezes, p/ 𝒏 ≥ 𝟏

e) 𝑛 𝑛 𝑛 𝑛
para i := 1 até 2n faça ( )

para j := 1 até i faça
S;
𝑛 𝑛)
→(

R: 𝟐𝟐𝒏 𝟏
𝟐𝒏 𝟏
vezes, p/ 𝒏 ≥ 𝟏

f) 𝑛
i := 1; 𝑘 ( *
enquanto (i ≤ 2n)
{ S;
i := i*2; R: 𝒏 𝟏 vezes, p/ 𝒏 ≥ 𝟏
}

g)
i := 2n;
enquanto (i ≥ 1)
{ S;
i := i div 2; // “div” é divisão inteira.
}
𝑛

Invertendo a ordem da progressão: 𝑘 ( *

𝑛 R: 𝒏 𝟏 vezes
𝑎 𝑎𝑘 𝑟

h)
i := 9; 𝑛
𝑘
enquanto (i ≤ n) 9
{ S;
i := i*3; R: 𝐥𝐨𝐠 𝟑 𝒏 𝟏 vezes, p/ 𝒏 ≥ 𝟐
}

i)
i := 1;
enquanto (i ≤ n e x ≤ A [i]) R: 𝒏 vezes, pois ainda que
{ S; 𝒙 > 𝑨[𝒊], o segundo laço
i := i + 1; completa a execução .
}
para j := i até n faça
S;
5. Calcule as complexidades de tempo e de espaço do algoritmo abaixo.

Algoritmo Termo3 (n)


Entrada: n, um número natural, isto é, n é inteiro e n
≥ 1.
Saída: t, o n-ésimo termo da sequência 3, 6, 9, ... .
{
i := 1; t := 0; t1 𝑇(𝑛) 𝑡 𝑡 (𝑛 ) 𝑡 𝑛
enquanto ( i ≤ n ) { t2 𝑇(𝑛) 𝑡 𝑡 𝑛 𝑡 𝑡 𝑛
t := t + 3; t3 Sejam: 𝑐 𝑡 𝑡 ∧ 𝑐 𝑡 𝑡
i := i + 1; 𝑻(𝒏) 𝒄𝟏 𝒄𝟐 𝒏 𝑶(𝒏)
} 𝑺(𝒏) 𝟑 𝑶(𝟏)
}
Não deveria escrever t ao final?
Embora se saiba que, em termos assintóticos, não faria diferença.

6. O algoritmo abaixo calcula o n-ésimo termo da sequência da Fibonacci (1, 1, 2, 3,


5, 8, 13, ...). Calcule a complexidade de tempo deste algoritmo. Supondo que você
possua um computador capaz de realizar 106 somas por segundo, quanto tempo este
computador levará para calcular o centésimo termo desta sequência.

Algoritmo Fibonacci (n)


Entrada: n, um número natural, isto é, n é inteiro e n ≥
1.
Saída: t, o n-ésimo termo da sequência de Fibonacci.
{
aa := 1; a := 1; f := 1; i := 3; 1 vez (4 instruções)
enquanto ( i ≤ n ) { (n+1-2) vezes (1 instrução)
aux := f; f := a + aa;
aa := a; a := aux; n-2 vezes (5 instruções)
i := i + 1;
}
retornar f; 1 vez (1 instrução)
}

( ) → Qtde de vezes que o laço é executado

( ) 9
→ 9 →
Calculando a complexidade de tempo do mesmo algoritmo com base num código Assembly:

READ n LOAD $3 LOAD a LOAD i


LOAD $1 STORE i ADD aa ADD $1
STORE aa L: LOAD n STORE f STORE i
LOAD $1 SUB i LOAD a JP L
STORE a JPC F STORE aa F: WRITE f
LOAD $1 LOAD f LOAD aux HALT
STORE f STORE aux STORE a

( ) 9 ( )
( ) 9
( ) ( )

( )
→ →

7. O algoritmo a seguir retorna o maior elemento em de um vetor. Calcule a


complexidade de tempo deste algoritmo.

Algoritmo Maior (A, n)


Entrada: A, um vetor de n elementos (n ≥ 1).
Saída: o maior elemento do vetor.
{
Max := A [1];
para i := 2 até n faça
se (Max < A [i])
Max := A [i];
retornar Max;
}

( ) ( )

8. O algoritmo a seguir ordena um vetor. Calcule a complexidade de tempo deste


algoritmo. O método de ordenação subjacente a este algoritmo é conhecido como
método da bolha (bubble sort).

Algoritmo BubbleSort (A, n)


Entrada: A, um vetor de n elementos (n ≥ 1).
Saída: o vetor A ordenado crescentemente.
{
para i := 1 até n - 1 faça
para j := 1 até n - i faça
se ( A [j] > A [j + 1] )
{
t := A [j];
A [j] := A [j + 1];
A [j + 1] := t;
}
retornar A;
}

( ) ( ) ( ) ( ) ( )

( ) ( ( ))
( )

( ) ( )

9. Outro algoritmo de ordenação conhecido como Selection Sort é apresentado a seguir.


Qual a sua complexidade? O algoritmo IndiceMenor, utilizado pelo
SelectionSort, retorna o índice do menor elemento do vetor X entre as posições
i e n, e a sua complexidade de tempo é T(n) = n – i + 1.

Algoritmo SelectionSort (X, n);


Entrada: vetor X com n elementos (n ≥ 1).
Saída: o vetor X ordenado em ordem crecente.
{
i := 1;
enquanto ( i ≤ n) {
m := IndiceMenor (X, n, i);
troca := X [i];
X [i] := X [m]; X [m] := troca;
i := i + 1;
}
retornar X;
}

( ) ( )
( )

( ) ( )

Ou, compreendendo a PA dentro de IndiceMenor:

( ) ( ) ( ) ( )
( )
( ) ( )
10. O que são as complexidades de pior caso (ou complexidade pessimista), melhor
caso (ou complexidade otimista) e de caso médio?

Complexidade de pior caso (ou pessimista) de um algoritmo refere-se ao teto de tempo


de execução deste algoritmo; isto é, as piores condições conforme as quais a execução
de um dado algoritmo implicaria o maior tempo possível, ou a função que expressa em
termos assintóticos esse limite máximo de tempo dentro do qual o algoritmo será
executado. Analogamente, a complexidade de melhor caso (ou otimista) refere-se ao
tempo mínimo necessário para a execução de um dado algoritmo; isto é, a função que
reflete as condições para o menor tempo de execução possível.

O caso médio é, considerando uma distribuição estatística de todos os casos, a média


entre todos os casos possíveis. Em outras palavras, refere-se ao ponto médio mais
provável da complexidade de tempo entre o pior caso e o melhor caso para a execução
de um dado algoritmo.

11. Uma modificação do algoritmo de ordenação BubbleSort é apresentada abaixo.


Nesta versão caso em uma passada verifica-se que o vetor está ordenado, então o
algoritmo pode ser encerrado. Calcule as complexidades de tempo de pior caso, de
melhor caso e de caso médio deste algoritmo.

Algoritmo BubbleSort (A, n)


Entrada: A, um vetor de n elementos (n ≥ 1).
Saída: o vetor A ordenado crescentemente.
{
troca := verdadeiro; i := 1
enquanto (i ≤ n e troca = verdadeiro)
{
troca := falso;
j := 1;
enquanto (j ≤ n – i)
{
se ( A [j] > A [j + 1] )
{
t := A [j];
A [j] := A [j + 1];
A [j + 1] := t;
Troca := verdadeiro;
}
j := j + 1;
}
i := i + 1;
}

retornar A;
}
Melhor caso: quando “A” já está ordenado

( )
Pior caso: quando “A” está ordenado decrescentemente

( ) (( ) )
( )

Caso médio: supondo que todos os casos são igualmente prováveis (distribuição
estatística uniforme)

Caso Passadas Complexidade do caso Probabilidade


1 1 n-1 1/n
2 2 n-1 + n-2 1/n
3 3 n-1 + n-1 + n-3 1/n
... ... ... 1/n
n-2 n-2 n-1 + n-2 + n-3 + ... (n-(n-2)) 1/n
n-1 n-1 n-1 + n-2 + n-3 + 2 + 1 1/n
n n n-1 + n-2 + n-3 + 2 + 1 + 0 1/n

( ) ( )( )
( )

( ) ( )

12. Esboce os gráficos das seguintes funções: log (n), n, n log (n), n2, 2n.

log
n n log
n
n

n² 2n
Todas as funções plotadas no mesmo gráfico:

2n

n log n

log n

13. Calcule o tempo em segundos, minutos, dias ou anos que gastaria um processador
capaz de realizar 106 operações por segundo para executar uma instância de tamanho
n = 100 de um algoritmo cuja complexidade é definida pelas funções:
log n, n , n, n log n, n2, n3, 2n, n! .

Quantidade de operações: 106 por segundo


1 operação = s= = 1 μs (microsegundo)

para n=100 1 μs =
Quantidade
Função segundos minutos dias anos
operações
6 μs 9 9

√ 10 μs
100 μs
664 μs 9

² 10000 μs
³ 1000000 μs
μs

9 μs 9 9
14. Ordene a lista de funções a seguir usando a notação O. Agrupe as funções que são Θ
uma da outra.

6n log n 2100 log log n log2n 2log n


22n n n0.01 1/n 4n3/2
3n0.5 5n 2n log2n 2n n log4 n
4n n3 n2 log n 4log n log n

1 ⁄ ( ) 6 (√ ) 11 ( ) 16 ( )
2 ( ) 7
√ (√ ) 12 ( ) 17 ( )
3 ( ) 8 (√ ) 13 ( ) 18 ( )
4
√ ( ) 9 ( ) 14 ⁄ ( ) 19 ( )

5 ( ) 10 ( ) 15 ( )

15. Mostre que:

a) n2 = O (n3).

Pela definição:
Escolho
. Válido ≥ ( )

b) nr = o (ns ) para r ≤ s.

Pelo Teorema 4:
( )
→ ( )
→ → → → , para > , sendo

c) 2n-1 = Θ (2n ).

Mostrando que ( ) [i]


Pela definição:
Escolho
→ → .
válido para ≥

Mostrando que ( ) [ii]


Pela definição: ≥
Como ≥ → , escolho ⁄
≥ → ≥ → ≥ → ≥ .
válido para ≥

, pela definição, ( ), para ≥ , pois ( ) [conforme i] e


( ) [conforme ii]
d) log a n = O (nb ), para a, b > 0.

Pelo Teorema 1: [ ( )] ( ( ) ), para > e >


Sendo ( ) , temos que:
[ ] ( )→[ ] ( )
Escolho (> )e (> ):
[ ] ( )
(> )
[ ] ( )
para ≥

e) n = o (n log n)

Sejam ( ) e ( )
Pelo Teorema 4:
( )
→ ( )
→ → → → , para >

f) log 3 n = o (n1/3)

Pelo Teorema 5: [ ( )] ( ( ) ), para > e >


Sendo ( ) , temos que:
[ ] ( )→[ ] ( )
Escolho (> )e (> ):

[ ] →[ ] ( ⁄ )

16. Mostre que logb (f (n)) = Θ (log (f (n)), para toda constante b > 1.

( ) ( ) ( )

Mostrando que ( ) ( ( )) [i]


Pela definição: ( ) ( )
( )
( )
Escolho
( ) ( )
válido para ≥

Mostrando que ( ) ( ( )) [i]


Pela definição: ( )≥ ( )
( )
( )≥
Escolho
( )≥ ( )
válido para ≥
, pela definição, ( ) ( ( )), para ≥ , pois ( )
( ( )) [conforme i] e ( ) ( ( )) [conforme ii]

17. Mostre que se f (n) = O (g(n)) e g(n) = O (h(n)) então f (n) = O (h (n)).

Sejam ( ) ( ) para > , e ( ) ( ) para > , tomando-se em


conta o limite superior de ( ), temos que: ( ) ( )
Com > e > , temos que > .
( ) ( )→ ( ) ( ( ))

18. Mostre que se f(n) = O(s(n)) e g(n) = O(r(n)) então f(n) + g(n) = O(s(n) + r(n)).

Por definição, há constantes , , e tal que ( ) ( ) para ≥ ,e


( ) ( ) para ≥

( ) ( ) ( ) ( )

Utilizando-se ( ), temos que


( ) ( ) ( ( ) ( )), válido para ≥ ( )
( ) ( ) ( ( ) ( ))

19. Ache um contra-exemplo para a afirmação: se f(n) = O(s(n)) e g(n) = O(r(n))


então f(n) - g(n) = O(s(n) - r(n)).

Seja ( ) e ( ) , temos: ( )
Seja ( ) e ( ) , temos: ( )
( ) ( ) ( ) ( )
( ) ( )
( ) ( ) ( ( ) ( ))

20. Alberto e Bernardo estão discutindo a performance de seus algoritmos de ordenação.


Alberto afirma que o seu algoritmo O (n log n) é sempre mais rápido do que o
algoritmo O (n2) de Bernardo. Para decidir, eles implementam em computador e
executam os dois algoritmos em uma série de dados de teste. Para o espanto de
Alberto, eles descobrem que quando n < 100 o algoritmo O (n2) é mais rápido e
apenas quando n ≥ 100 é que o algoritmo O (n log n) é mais rápido. Explique como
esta situação pode ocorrer. Se for preciso, forneça exemplos numéricos.

Assintoticamente, podemos afirmar que, para valores de suficientemente grandes,


um algoritmo ( ) será sempre mais rápido que um algoritmo ( ); isto é,
com tendendo ao infinito, a partir um determinado ponto (chamemos ), o
segundo algoritmo assumirá sempre valores superiores aos do primeiro,
independente de valores constantes possivelmente influentes. Em outras palavras,
haverá sempre um ponto a partir do qual, sejam quais forem os valores constantes
que pesem em ambas as funções, estes serão anulados pela força de crescimento de
cada função, de modo que, a partir de então, ( ) será sempre superior
(crescimento mais acentuado, execução mais demorada) do que ( ). Esta
intersecção em , portanto, é determinada em função destes valores constantes das
complexidades de tempo ( ( ) e ( )) de cada algoritmo, não desprezíveis no
intervalo pré-assintótico. No caso descrito, concluímos, portanto, a existências de
constantes e , maiores que zero, respectivamente influentes do comportamento
pré-assintótico das funções de complexidade ( ) e ( ), tal que .

Para , sejam ( ) , com > e > , e ( ) ,


com > :

Para ≥ , temos que


Escolhendo

Para , temos que >


Escolhendo
99 99 > 99
99
>
99
9 >

( )> ( ), para , , e 9

_________

Outra forma de resolver – escolher um valor único para c e mostrar p/ n=100 e n=99:

Prova de que ( )
Pela definição:
Sabendo que para ≥ , , temos que

Escolho

Para 99, onde >


99 99 > 99 → >

21. A segurança de comunicações é extremamente importante em redes de


computadores e, uma forma típica de garanti-la é criptografar as mensagens. Sistemas
criptográficos típicos para a transmissão segura de dados através de redes são
baseados no fato de que não são conhecidos algoritmos eficientes para a fatoração de
números inteiros muito grandes. Assim, se podemos representar uma mensagem
secreta como um grande número primo p, podemos transmitir pela rede o número r
= p . q, onde q > p é outro grande número primo que serve como chave de
encriptação. Um espião que obtenha o número r transmitido teria de fatorá-lo para
descobrir a mensagem secreta p.
Usar fatoração para descobrir a mensagem é bastante difícil sem que se conheça a
chave q. Para entender por que, considere o seguinte algoritmo simples de
decifração:

Para cada inteiro tal que 1 < p < r, verifique se p divide r. Se dividir, imprima
que “ A mensagem secreta é p” e, caso contrário, continue.

Algoritmo: DecodificarMensagem(r)
Entrada: r, inteiro, r > 1
Saída: mensagem decodificada (p), um número primo
{
p := 2;
encontrou_p := false;
enquanto (p < r – 1 e encontrou_p = false) {
se ((r mod p) = 0) {
encontrou_p := true;
imprima “A mensagem secreta é ” + p
}
p := p + 1;
}
}

a) Suponha que um espião use esse algoritmo em um computador que possa


realizar em 1 microssegundo (10-6 segundo) a operação de divisão entre dois
inteiros de 100 bits cada um. Forneça uma estimativa do tempo necessário, no
pior caso, para decifrar a mensagem secreta se r possui 100 bits.

Pior caso: ( ) (√ ), já que e (o algoritmo executa de 2 até p,


o menor número primo fator da multiplicação ). Como , não pode
ser número quadrado; por isso “o” e não “O”.

Entrada: r, número inteiro da ordem de . Assim,

√ μs ( )

9 segundos anos

b) Qual a complexidade do algoritmo acima? Dica: a entrada do algoritmo é um


grande número r, cujo tamanho n é o número de bytes necessários para armazená-
lo. Ou seja, em bytes, n = log2 (r) / 8. Suponha que cada divisão pode ser
realizada em um tempo proporcional ao tamanho de r.

Sendo, ⁄ , temos que:

( ) ( ) ( ) ( )
22. Dê um exemplo de uma função positiva f (n) de tal forma que f (n) não seja nem
O (n), nem Ω (n).

( ) , pois ( ) oscila entre e , ora constante, ora superior a


( ).

23. Prove por indução que a soma das n + 1 primeiras potências inteiras de 2, isto é, 1 +
2 + 4 + ... + 2n, é S (n) = 2n+1 – 1.

Base:
( ) [ ]

Redução:
( )
( )
( ) ( )

Hipótese de indução:
( )

Prova:
( ) ( )

24. Prove por indução que a soma 1 + 3 + 5 + ... + 2n – 1 = n2, i.e., a soma de números
ímpares sempre é um quadrado perfeito.

Redução:
( ) ( )
( ) ( )
( ) ( )

Hipótese de indução:
( ) ( )

Prova:
( ) ( ) ( )

Bases:
( ) [ ]
( ) [ ]

25. Prove que se n é um número natural e 1 + x > 0, então (1 + x)n ≥ 1 + nx.

Base:
( ) ≥ → ≥

Redução:
( ) ( )( )
Hipótese de indução:
( ) ≥ ( )

Prova:
( ) ≥( ) ( ( ) )
( ) ≥( ) ( )
( ) ≥
( ) ≥
( ) ≥ ( )

Como ( ) ≥ , temos que, reduzindo este termo, o lado direito da inequação


fica ainda menor que o lado esquerdo, e, portanto, por indução:

( ) ≥

26. Prove que numa sequência de números naturais onde ak = ak-1 + r sendo r uma
constante, a soma dos n primeiros números desta sequência é
S(n) = a1 + a2 + ... + an = n (an + a1)/2.

Redução:
( )
( )
( ) ( )

Hipótese de indução:
( )( )
( )

Prova:

Como , e, portanto, , temos que:


( )( )
( )

Como ( ), e, portanto, , temos que:


( )
( )( *
( )
( ) ( )
( )( *
( )
( ) ( )
( )
( ) ( )
( )

( )
( )
( )
Base:
( )
( )

27. Prove que a quantidade de nós de uma árvore binária cheia é igual a 2h+1 – 1, onde h
é a altura da árvore. Uma árvore binária cheia é uma árvore para a qual, se v é um
nó de alguma de suas subárvores vazias, então v se localiza no último nível.

Redução:
( )
( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( )
( ) ( )

Hipótese de indução:
( )

Prova:
( )
( )
( )
( )

Bases:
( )
( )

28. Ache uma fórmula em função de n que representa o valor de T(n) = 8 + 13 + 18 +


23 + ... + (3 + 5n). Prove que sua fórmula é válida.

Fórmula:
( )
( )

Redução:
( ) ( ( )) ( )
( ) ( ( ))
( ) ( ) ( )

Hipótese de indução:
( ) ( ( ) ) ( ) ( )
( )

Prova:
( ) ( )
( ) ( )

( )
( )
( )

29. Ache uma expressão para a soma da i-ésima linha do triângulo abaixo. Prove que
sua expressão é verdadeira.

1 = 1
3 + 5 = 8
7 + 9 + 11 = 27
13 + 15 + 17 + 19 = 64
21 + 23 + 25 + 27 + 29 = 125

Fórmula:

Observações preliminares:
1. uma linha i contém i termos; isto é ;
2. cada linha contém um termo a mais que a linha anterior; isto é ;
3. cada linha é uma PA de razão 2 (r=2)

( )
[Qtde. total de termos acima da i-ésima linha]

[Primeiro termo da i-ésima linha]

( )
( ) [Último termo da i-ésima linha]

( ) ( )
( )
() ( )⁄ [Soma dos termos da i-ésima linha]
(( ) ( ) )
()

(( ) ( ))
()

( ( ))
()

()

Redução:
( ) ( ( )) [Primeiro termo da i-ésima linha deduzido a
() ( * partir da soma da linha ( )]

() ( )
[Último termo da i-ésima linha deduzido a
partir do primeiro termo]
() ( )

() ( ) ( )

() ( )

[Soma da linha i+1 deduzida a partir do


último termo da i-ésima linha, e, portanto,
da soma da i-ésima linha, S(i+1) = f(S(i))]

() ( ) () ( )
( * ( *
( ) ( ) ( ,

() ( )
( *
( ) ( ) ( ,

() ( )
( ) ( ) (( ) +

()
( ) ( ) ( ( ) )

()
( ) ( ) ( ) ( ) (( ) )

()
( ) ( ) ( ) ( ) (( ) )

() ( ) ( ) (( ) )

( ) ( ) (( ) ) [A]
()

Hipótese de indução:
[B]
( ) ( )

Prova:
( ) ( ) (( ) ) [Substituindo B em A]
()

() ( ) (( ) )
() (( ) )
() (( ) )
() ( )
() ( )

Bases:
( )
( )

30. Ache uma expressão para a seguinte soma e prove que ela é verdadeira:
1 . 2 + 2 . 3 + ... + n(n + 1).

Fórmula:

( )

( )

( )

( )
( )
( ) ( ( )) ( ( ))

( )
( ) ( ( ) ( ) ( ) )

( )
( ) ( )( ( ))

( )
( ) ( ( )( ))

( )
( ) ( )

( )

Redução:
( ) ( ) ( )

Hipótese de indução:
( ) ( ) ( )
( )
Prova:
( ) ( ) ( )
( ) ( )

( ) ( ) ( )
( )

( )

( )

Base:
( ) ( )
( ) ( )

31. Ache uma expressão para a seguinte soma e prove a sua afirmação.

1 1 1 1
+ + + ... +
n
2 4 8 2

Fórmula:
[Soma da PG de razão ½, com 𝑎 ½]

( )

( )

( )

( ) ( *

( )

Redução:

( )

( )

( ) ( ) ⁄
Hipótese de indução:

( )

Prova:

( )

( )

( )

( )

( )

( )

( )

Base:

( )

32. Prove que xn – yn é divisível por x – y para todos os números naturais x, y (x ≠ y) e


n.

Redução:

( ) ( )
( ) ( ) ( )

Hipótese de indução:
é divisível por , para ≥ e .

Prova:
( ) ( ) ( )
é divisível é divisível é divisível por
inteiro inteiro inteiro hipótese
é divisível por , .

Bases (redução de 2 em 2):


Para
é divisível por
Para
( ) ( )
é divisível inteiro

33. Prove a seguinte inequação:

para todo n ≥ 1.

Teorema:

( )

Base ( ):

( )

Redução:

( )

( )

( ) ( *

( ) ( )

Hipótese de indução:

( )

Prova:

( )
( )

( )
_________

Outra forma de resolver:


Mostrar que ( ) , conforme realizado no exercício 31.

Então, obviamente, ≥ , pois sempre > .

34. Prove que é possível estabelecer uma coloração válida para as regiões formadas por
qualquer número de linhas no plano com somente duas cores. Observação: uma
coloração é válida se todas as regiões vizinhas estão coloridas com cores diferentes.
Duas regiões são consideradas vizinhas se somente se elas possuem um lado em
comum.

Base ( ):

Hipótese:
É possível colorir as regiões de um plano cortado por n linhas com apenas 2 cores.
Prova:
Ao traço da n-ésima linha, divide-se o plano em 2 grupos de regiões, de acordo com
o lado da linha em que se encontram no plano. Para as regiões de um dos dois
grupos devem ser mantidas as cores que possuía antes da n-ésima linha. As regiões
do outro grupo devem ter suas cores invertidas.
Antes da n-ésima linha Com a n-ésima linha, antes da Com a n-ésima linha, após a
troca de cores troca de cores no LADO B

Dadas 2 regiões vizinhas e . Por hipótese, elas possuíam cores opostas antes da
n-ésima linha. Mesmo que estejam no grupo (lado da n-ésima linha) cujas cores das
regiões serão invertidas, ainda assim possuirão cores distintas após a inversão. Se
e foram cortadas pela n-ésima linha, então as respectivas duas novas regiões
criadas (no mesmo lado) terão suas cores trocadas, enquanto as duas restantes (do
outro lado) serão mantidas, de modo que novamente todas as regiões vizinhas
possuirão cores opostas.

35. Utilizando indução, prove que o algoritmo a seguir calcula o fatorial de um número
inteiro n ≥ 2.

Algoritmo Fatorial (n)


Entrada: n, inteiro, n ≥ 2.
Saída: n! .
{
i := 1; f := 1;

repita
{
i := i + 1;
f := f * i;
}
até i = n;

retornar f;
}

Base ( ):
( )
Laço executa 1 vez,

Redução:
( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( )
( )
( )

Hipótese de indução:
( ) ( )

Prova:
( )
( )

Como ( ) ( ), temos que


( )

36. Aplicando a técnica de design de algoritmos indutivos estudada, escreva algoritmos,


calcule as suas complexidades, para resolver os seguintes problemas:

a) Calcular o menor elemento de um vetor de n elementos.

i) Interface: ii) Significado

( ) Retorna o índice do menor valor


dentre n elementos do vetor A.

iii) Redução

m = Menor(A, n-1)
se (A[n] < m) {
retornar A[n]
} senão {
retornar m
}

iv) Base (redução de 1 em 1)

Proponho base para retornar A[1]

v) Algoritmo inteiro

Menor(A, n){
se ( ) {
retornar A[1]
} senão {
m = Menor(A, n-1)
se (A[n] < m) {
retornar A[n]
} senão {
retornar m
}
}
}

vi) Complexidade

( )
( ) ( )

( )
( ) ( )
( ) ( )
( ) ( )

b) Multiplicar dois números naturais x e y (x ≥ 0 e y ≥ 0).

i) Interface: ii) Significado

( ) Retorna o produto da multiplicação


entre x e y.

iii) Redução (indução em x)

( ) ( )

iv) Base (redução de 1 em 1)

Proponho base para retornar 0

v) Algoritmo inteiro

( ) {
se ( ou ) {
retornar 0
} senão {
retornar ( )
}
}

vi) Complexidade

( )
( ) ( ) , para ≥

( )
( ) ( )
( ) ( )
( ) ( )
( ) ( )
c) Somar os elementos de um vetor A de n elementos (n ≥ 1).

i) Interface: ii) Significado

( ) Retorna a soma dos n elementos de


um vetor A.

iii) Redução

( ) ( ) [ ], para ≥

iv) Base (redução de 1 em 1)

p/ retornar A[1]

v) Algoritmo inteiro

( ) {
se ( ) {
retornar A[1]
} senão {
retornar ( ) [ ]
}
}

vi) Complexidade

( )
( ) ( ) , para ≥

Pelo método da iteração progressiva:

( )
( ) ( )
( ) ( )
( ) ( )
( ) ( )

d) Inverter os elementos de um vetor A de n elementos (n ≥ 1), ou seja, se


A = [1 3 5 -2 0 4] então, após invertido, A = [4 0 -2 5 3 1].

i) Interface: ii) Significado

( ) Inverte in loco a posição dos n


elementos entre i (inclusive) e j
(inclusive) de um vetor A.
iii) Redução

Invertem-se os termos centrais do vetor – isto é, todos menos o primeiro e o


último –, depois colocamos o último termo no lugar do primeiro e o
primeiro no lugar do último. O vetor de saída será algo como:

[]
( ) [ ( )]
[]
Como, , temos que redução em n ocorre de 2 em 2.

iv) Base (redução de 2 em 2)

p/ NÃO FAZ NADA

v) Algoritmo inteiro

( ) {
se ( > ) {
[]
[] []
[]
( )
}
}

vi) Complexidade

( ) ( )
( ) ( ) , para ≥

Pelo método da iteração progressiva:

( )
( )
( ) ( )
( ) ( )
( ) ( )
( ) ( )
( ) ( )
( ) ( )

( ) ( )
e) Somar os elementos de uma matriz A de n linhas e m colunas (n ≥ 1, m ≥ 1).

i) Interface: ii) Significado

( ) Retorna a soma dos elementos de


uma matriz de linhas e
colunas.

iii) Redução

( ) ( [ ] [ ] [ ]) ( )

iv) Bases (redução de 1 em 1 em )

p/ retornar 0

v) Algoritmo inteiro

( ) {
se ( ) {
retornar ( ) [ ]
} senão {
se ( ) {
retornar 0
} senão {
retornar ( ) [ ]
}
}
}

vi) Complexidade

( ) ( )

f) Calcular o n-ésimo termo da sequência da Fibonacci (1, 1, 2, 3, 5, 8, 13, ...).

i) Interface: ii) Significado

( ) Retorna o n-ésimo termo da


sequência de Fibonacci.

iii) Redução

( ) ( ) ( ), para >
iv) Base (redução de 2 em 2)

p/ retornar 1

p/ retornar 1

v) Algoritmo inteiro

( ) {
se ( ) {
retornar 1
} senão {
retornar ( ) ( )
}
}

vi) Complexidade

( ) ( )
( ) ( ) ( ) , para >

Pelo método da iteração progressiva:

( )
( )
( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )

Pelo método da substituição:

a) Conjectura ( ) ( )

NÃO É POSSSÍVEL PROVAR

b) Conjectura ( ) ( )

( ) , para > e ≥

Base : Base :
( ) ( )

≥ ≥

Hipótese e indução:
( )
( )
Prova:
( ) ( ) ( ) ( )
( )
Escolho (atende restrições – definição e bases)

( ) ( )

37. Desenvolva um algoritmo recursivo para obter o valor de um polinômio de grau n


no ponto igual a x. Qual a complexidade do seu algoritmo? Você seria capaz de
desenvolver um algoritmo com complexidade de tempo não superior a O (n)?

i) Interface: ii) Significado

( ̅ ) Resolve um polinômio de grau n,


base x, e coeficientes
(representados no
vetor ̅.

iii) Redução

( ̅ )
( ̅ )
( ̅ ) ( ̅ )

iv) Base (redução de 1 em 1)

p/ retornar

v) Algoritmo inteiro

( ̅ ) {
se ( ) {
retornar
} senão {
retornar ( ̅ )
}
}

vi) Complexidade
( )
( )
( ) ( ) ( )

multiplicações no -ésimo termo = ( ) multiplicações da potência + 1


do coeficiente.

( ) multiplicações no ( )-ésimo termo = ( ) multiplicações da


potência + 1 do coeficiente.

( ) ( )

Repensando o algoritmo para obter uma complexidade de tempo não superior a


( )

iii) Redução

( ̅ )
( ̅ )
( ̅ ) ( ̅ )

isto é:
( ̅ ) (( (( ) ) ) )

iv) Base (a mesma)

p/ retornar

v) Algoritmo inteiro (iterativo, método de Horner)

( ̅ ) {

para até faça {

vi) Complexidade

( ) multiplicações adições
( ) ( )

38. Desenvolva um algoritmo que calcule o maior e o menor elemento de um vetor de n


elementos de tal modo que a quantidade de comparações do seu algoritmo não seja
maior do que 3n/2.

39. Desenvolva uma versão com redução do tipo “dividir para conquistar” para os
seguintes algoritmos. Calcule as complexidades de pior caso de cada um deles e
diga, em cada caso, se melhorou, piorou ou continuou igual às complexidades em
relação àquelas outras de soluções diferentes desenvolvidas em sala de aula ou nesta
lista de exercícios.

a) Calcular a soma dos n primeiros naturais;

i) Interface: ii) Significado

( ) Retorna a soma dos números naturais


entre os números (inclusive) e
(inclusive), sendo e dois números
da série dos primeiros números
naturais.

iii) Redução

( )
( ) ( ) ( )

iv) Bases

p/ retornar i

p/ > retornar 0

v) Algoritmo inteiro

( ) {
se ( > ) {
retornar 0
} senão {
se ( ) {
retornar i
} senão {
( )
retornar ( ) ( )
}
}
}

vi) Complexidade

sendo
( ) ( )

Aplicando o teorema para resolução de recorrências do tipo “dividir para


conquistar”:

, , ,
>
( ) ( ) ( )

b) Calcular o menor elemento de A, um vetor de n elementos.

i) Interface: ii) Significado

( ) Retorna a o menor valor no vetor


dentro do intervalo delimitado pelos
índices e .

iii) Redução

( )
( )
( )
se ( ) { retornar } senão { retornar }

iv) Bases

p/ retornar []

p/ > retornar null

v) Algoritmo inteiro

( ) {
se ( > ) {
retornar null
} senão {
se ( ) {
retornar [ ]
} senão {
( )
( )
( )
se ( ou null) {
retornar
} senão {
se ( > ou null) {
retornar
} senão {
retornar null
}
}
}
}
}
vi) Complexidade

sendo
( ) ( )

Aplicando o teorema para resolução de recorrências do tipo “dividir para


conquistar”:

, , ,
>

( ) ( ) ( )

40. Considere a equação de recorrência a seguir:

T(n) = T(n - 1) + 4
T(1) = 4

Demonstre, por indução, que T(n) = 4n.

i) Base para

Pela relação de recorrência:


( )

Pela fórmula:
( )

A base é verdadeira

ii) Hipótese de indução

( ) ( )

iii) Prova

( ) ( )
( )
( )

41. Use a indução matemática para mostrar que a solução da relação de recorrência
abaixo é T(n) = n log n.

T(n) = 2 T(n/2) + n, para n = 2k, k > 1.


T(2) = 2

i) Base, para

Pela fórmula:
( )

Pela relação de recorrência:


( )

A base é verdadeira

ii) Hipótese de indução

( )

iii) Prova

( )

( )
( ) ( )
( ) ( )
( )
( )

42. Escreva um algoritmo para resolver o problema clássico das Torres de Hanói. Qual
a complexidade do seu algoritmo?

Problema das Torres de Hanói: deslocar discos de uma torre A para uma torre B,
usando uma terceira torre como auxiliar (C), de modo que nunca um disco de
tamanho maior seja colocado sobre um disco de tamanho menor.

Pensando indutivamente: deslocar um único disco ( ) é trivialmente simples.


Se eu souber como deslocar discos, o deslocamento do -ésimo disco (maior
disco de todos) e, depois, dos discos para cima dele se torna igualmente
simples. Portanto:

i) Interface: ii) Significado

( ) Desloca discos de diferentes


tamanhos de uma torre de origem
para uma torre de destino
usando uma torre como auxiliar,
de modo que jamais um disco de
tamanho maior seja colocado sobre
outro de tamanho menor.

iii) Redução

( )
( )
( ) [detalhes do procedimento
abstraídos do contexto /
significado: desloca o 1º disco de
uma torre de origem para uma
torre de destino ]
( )

iv) Base (redução de 1 em 1)

p/ ( )

v) Algoritmo inteiro

( ) {
se ( ) {
( )
} senão {
( )
( )
( )
}

vi) Complexidade

( )
( ) ( )

Pelo método da iteração progressiva:

( )
( ) ( )
( ) ( )
( ) ( )
( ) ( )
( ) ( )
( )
( ) ( )

Mais genericamente observável em:

( ) ( )
( ( ) ) ( )
( ( ) ) ( )
( )
( ) ( )

Como:
( )
[soma de uma PG de k termos,
e ]
Temos que:
( ) ( )
( ) ( ( ) ) [para ]
( ) ( ( ( )) )
( ) ( ( ) )
( )
( )
( ) ( )

43. O problema das Torres de Saigon é semelhante ao das Torres de Hanói exceto pelo
fato de que você pode contar com 4 hastes em vez de três. Escreva um algoritmo
para resolver o problema das Torres de Saigon. Qual a complexidade do seu
algoritmo?

Usando-se o mesmo método descrito para o problema clássico das Torres de Hanói,
deslocam-se os primeiros discos da pilha da torre de origem ( ) para uma torre
intermediária ( ) usando uma torre auxiliar ( ), sendo todas estas torres,
obviamente, diferentes da torre de destino ( ). Em seguida, deslocam-se os
discos restantes em para usando como auxiliar. Finalmente, deslocam-se os
discos em pata usando novamente como auxiliar.

Complexidade:

( ) ( ) ( )
( ) ( )

Você também pode gostar