Saltar al contenido principal
Muchos problemas se pueden resolver dividiéndolos en subproblemas más pequeños, como en divide y vencerás. Pero a veces esos subproblemas se repiten una y otra vez, y resolverlos cada vez desde cero dispara el tiempo de forma exponencial. La programación dinámica guarda el resultado de cada subproblema la primera vez que se calcula y lo reutiliza. Con esa idea tan simple, problemas que tardarían siglos se resuelven en milisegundos.

Lo que vas a aprender

  • Cuándo se puede aplicar programación dinámica.
  • La diferencia entre memoización y tabulación.
  • Cómo plantear el estado y la recurrencia de un problema.
  • Cómo reconstruir la solución, no solo su valor.
  • Los problemas clásicos: monedas, mochila, subsecuencia común y distancia de edición.

Fundamentos teóricos

Cuándo se aplica

Un problema se presta a programación dinámica si tiene:
  1. Subestructura óptima: la solución óptima se construye a partir de soluciones óptimas de subproblemas.
  2. Subproblemas solapados: los mismos subproblemas aparecen muchas veces.
Si los subproblemas no se repiten, basta con divide y vencerás. Si además se puede decidir en cada paso sin mirar atrás, puede bastar un algoritmo voraz.

Ejemplo: Fibonacci

F(n)=F(n−1)+F(n−2)F(n) = F(n-1) + F(n-2). La recursión directa recalcula lo mismo muchísimas veces: F(50)F(50) hace unos 4⋅10104\cdot10^{10} llamadas. Guardando los resultados, solo hay 51 subproblemas distintos.

Memoización (de arriba abajo)

Se escribe la recursión normal y se guarda cada resultado en una tabla:

Tabulación (de abajo arriba)

Se rellena la tabla empezando por los casos más pequeños, sin recursión:

Cómo plantear un problema

  1. Estado: ¿qué parámetros definen un subproblema? Por ejemplo, dp[i][w]dp[i][w]: el mejor valor con los ii primeros objetos y capacidad ww.
  2. Recurrencia: ¿cómo se obtiene un estado a partir de otros más pequeños?
  3. Casos base.
  4. Orden de cálculo: que cada estado se calcule después de aquellos de los que depende.
  5. Respuesta: ¿qué estado contiene la solución?
El coste es (número de estados) × (trabajo por estado).

Problemas clásicos

Ejemplos resueltos

Ejemplo 1 · Cambio de monedas

Mínimo de monedas para pagar 11 con monedas de 1, 5 y 6.
El algoritmo voraz (coger siempre la moneda más grande) daría 6 + 1 + 1 + 1 + 1 + 1 = 6 monedas.
Capacidad 7; objetos (peso, valor): (1, 1), (3, 4), (4, 5), (5, 7).
La mejor opción es llevar los objetos de peso 3 y 4 (valor 9). Recorrer ww hacia atrás permite usar una sola fila.
Entre "ABCBDAB" y "BDCABA":
Es lo que usa diff para comparar ficheros, y se usa también para alinear secuencias de ADN.
Mínimo de inserciones, borrados y sustituciones para pasar de "gato" a "pato": 1. De "casa" a "calle": 3.
Es la base de los correctores ortográficos.
Para saber qué objetos van en la mochila, se guarda la tabla completa dp[i][w]dp[i][w] y se recorre hacia atrás: si dp[i][w]≠dp[i−1][w]dp[i][w] \ne dp[i-1][w], el objeto ii está dentro y se pasa a w−piw - p_i.

Errores frecuentes

  • No identificar bien el estado. Si falta información en el estado, la recurrencia no es correcta.
  • Calcular estados en un orden equivocado en la tabulación, usando valores aún no calculados.
  • En la mochila 0/1 con una fila, recorrer ww hacia delante: cada objeto se usaría varias veces (eso es la mochila ilimitada).
  • Aplicar un algoritmo voraz donde no funciona, como el cambio de monedas con valores arbitrarios.
  • Usar memoización con mucha profundidad en lenguajes con pila limitada.

Preguntas frecuentes

Richard Bellman eligió el nombre en los años 50, según contó, porque sonaba bien y ocultaba que hacía investigación matemática a un secretario de Defensa que la detestaba. “Programación” significaba planificar, no escribir código.
En el GPS y los mapas (caminos mínimos), en la bioinformática (alineamiento de secuencias), en el reconocimiento de voz (algoritmo de Viterbi), en el control óptimo, en los compiladores y en finanzas (valoración de opciones).

Temas relacionados

Recursión en C

La pila de llamadas paso a paso.

Divide y vencerás

Cuando los subproblemas no se repiten.

Notación asintótica

Medir el coste de los algoritmos.
Última modificación el 12 de octubre de 2026