Estructuras de Datos y Algoritmos · Programación

Programación dinámica y voracidad

Reconocer cuándo un problema admite solución voraz y cuándo requiere programación dinámica, apoyándose en subestructura óptima y subproblemas traslapados.

Programación dinámica y voracidad

Diagrama de estructuras de datos: arbol binario, lista enlazada y tabla hash.
Estructuras de datos fundamentales y analisis de complejidad algoritmica.

Mapa conceptual

Apostar al presente contra guardar el pasado Dos estrategias para optimizar. La voraz decide ya y no mira atrás. La programación dinámica decide después de haber resuelto los pedazos, y los recuerda. Saber cuál aplica es el corazón de muchos problemas de entrevista y de investigación de operaciones.

Los dos ingredientes

Programación dinámica

La programación dinámica (DP) explota ambos ingredientes: resuelve cada subproblema una vez y guarda su resultado. Se implementa por arriba (memoización, recursión con caché) o por abajo (tabulación, rellenar una tabla). Convierte un algoritmo exponencial en uno polinomial.

El ejemplo de Fibonacci

Calcular fib(n) = fib(n−1) + fib(n−2) por recursión pura es exponencial por recomputar. Con memoización es O(n): cada valor se calcula una vez. Es el ejemplo mínimo de DP: subproblemas traslapados y una recurrencia clara.

Estrategia voraz

La voracidad toma en cada paso la opción que parece mejor AHORA (máximo beneficio local) esperando llegar al óptimo global. Es simple y rápida, pero solo es válida cuando una elección local segura no arruina el futuro: cuando el problema tiene la propiedad de elección voraz.

La voracidad exige una justificación (a un intercambio); si falla, se va a DP.
ProblemaVoraz funcionaHace falta DPPor qué
Monedas canónicasSi—cada moneda grande nunca estorba
Monedas arbitrariasNo siempreSitomar la mayor puede no dar el mínimo
Mochila 0-1NoSilo mejor por unidad de peso puede no caber óptimo
Intervalos (agendar máx.)Si—elegir el que termina antes es seguro

¿Qué distingue a la programación dinámica de la simple recursión divide y vencerás?

El cambio de monedas, caso vivo

Con monedas 1, 3, 4 y objetivo 6: lo voraz toma la de 4 y luego dos de 1 (tres monedas). Lo óptimo son dos de 3. La voraz falla porque la moneda más grande no garantiza el mínimo total: hace falta DP sobre «mínimo monedas para cada importe».

Mochila

En la mochila 0-1, ordenar por valor/peso y meter lo más rentable (voraz) puede dejar un hueco caro. DP define «mejor valor con los ítems hasta i y capacidad w» y explora incluir o no en O(n·capacidad).

Si un problema no tiene subproblemas traslapados, la programación dinámica ofrece ventaja sobre la recursión directa.

Errores frecuentes

Cómo decidirse

  1. ¿Tiene subestructura óptima? Si no, ninguno de los dos sirve (busca otra vía).
  2. ¿Se puede justificar una elección local segura? Sí → voraz; es más simple y rápido.
  3. ¿Los subproblemas se traslapan y no hay garantía voraz? → DP, define el estado con cuidado.

Vocabulario de optimización

subestructura óptima
lo óptimo global usa lo óptimo de las partes
traslape
los mismos subproblemas reaparecen
memoización
DP de arriba, recursión con caché
tabulación
DP de abajo, rellenar tabla
elección voraz
decisión local segura y final

Wikipedia
Programación dinámica, ejemplos y comparación con voracidad.

Explica por qué «dar el cambio con el mínimo número de monedas» es resolvable voraz con monedas comunes pero requiere DP con un sistema arbitrario. Da un contraejemplo concreto.

VisuAlgo
Visualizaciones animadas de estructuras de datos y algoritmos.