Uno de los ejemplos más sencillos (más que los vistos en clase) de aplicación de la programación dinámica es el cálculo del término n-ésimo de la sucesión de Fibonacci.
La definición de la sucesión o función de Fibonacci es:
Fib(n) = 1, si n = 0,1
Fib(n) = Fib(n-1) + Fib(n-2), si n > 1
La solución más natural para calcular el término n-ésimo serÃa, por tanto, traducir esa definición recursiva de la función a nuestro pseudocódigo:
función FibRec(n:natural) devuelve natural
principio
si n≤1 entonces
devuelve 1
sino
devuelve FibRec(n-1)+FibRec(n-2)
fsi
fin
El inconveniente de esa solución es su coste, exponencial en el valor de n. La ineficiencia de FibRec se debe a que se producen llamadas repetidas de la función para calcular valores que ya se habÃan calculado previamente, no se ha conservado su resultado, y por tanto hay que volver a calcularlos.
La solución de programación dinámica pasarÃa por utilizar una tabla auxiliar en la que almacenar las soluciones de todos los “subproblemas” (valores de Fib para valores menores que n) resueltos:
El algoritmo iterativo para devolver el n-ésimo término de Fibonacci calculando la tabla serÃa:
función FibIterProto(n:natural) devuelve natural
variables i:natural; T:vector[0..n] de natural
principio
si n≤1 entonces
devuelve 1
sino
T[0]:=1;
T[1]:=1;
para i:=2 hasta n hacer
T[i]:=T[i-1]+T[i-2]
fpara;
devuelve T[n]
fsi
fin
El último paso en la mejora proviene de detectar que en el algoritmo anterior no es necesario todo el vector auxiliar, pues basta con almacenar los dos últimos valores calculados:
función FibIter(n:natural) devuelve natural
variables i,suma,x,y:natural {x e y para almacenar los dos últimos
términos calculados y suma para almacenar el actual}
principio
si n≤1 entonces
devuelve 1
sino
x:=1;
y:=1;
para i:=2 hasta n hacer
suma:=x+y;
y:=x;
x:=suma
fpara;
devuelve suma
fsi
fin