Dado um valor de troco N (um número inteiro no nosso exemplo).
Nós temos suprimento infinito de cada tipo de moeda do conjunto S = {S1, S2, .., SM}.
Note que temos portanto M tipos de moedas e teoricamente temos infinitas delas.
Quantas maneiras podemos combinar as moedas para obter um troco exato?
A ordem das moedas não importa.
Por exemplo temos que dar um troco de N = 4 dinheiros.
O conjunto de moedas que temos é S = {1,2,3}.
Podemos ver que existem quatro soluções: {1,1,1,1}, {1,1,2}, {2,2}, {1, 3}.
Assim a resposta do programa deve ser 4.
Este problema pode ser resolvido por DP. Identificamos as duas características:
1) Subestrutura ótima
Para contar soluções, podemos dividir todas as soluções em dois subconjuntos:
a) Todas as soluções que não contêm moeda "i" (ou seja Si).
b) As soluções que contêm pelo menos uma moeda Si.
Desta forma podemos escrever o problema de contagem como
C(S, n) = C(S', n) + C(S, N-Si)
Onde S' = S - {Si}
Desta forma vemos que o problema tem a propriedade subestrutura ótima como o problema pode ser resolvido usando soluções de subproblemas. A equação e as condições abaixa deixam claro também que os problemas são sobrepostos.
Temos que notar que existem algumas condições:
a) C(S,0) = 1, pois se n=0 existe uma solução que não precisa de mais moedas
b) C(S,n) = 0, se n<0, pois n negativo, não há uma solução do problema (subtraiu demais)
c) C(S,n) = 0, se S = {} e n > 0, pois se não temos moedas para dar um troco "n" (já que n é maior que zero), não tem como acharmos uma solução.
O que falta no exemplo acima? Se você falou a memorização dos dados... acertou!
A memorização aumenta bastante a velocidade, uma vez que não precisamos recalcular.