Se trata de un problema de programación dinámica clásica (tenga en cuenta que el primer algoritmo voraz no siempre funciona aquí!).
Suponga que las monedas están ordenadas de modo que a_1 > a_2 > ... > a_k = 1
. Definimos un nuevo problema. Decimos que el problema (i, j)
es encontrar el número mínimo de monedas que hacen el cambio para j
usando monedas a_i > a_(i + 1) > ... > a_k
. El problema que deseamos resolver es (1, j)
para cualquier j
con 1 <= j <= n
. Supongamos que C(i, j)
es la respuesta al problema (i, j)
.
Ahora, considere una instancia (i, j)
. Tenemos que decidir si estamos usando o no una de las monedas a_i
. Si no lo estamos, solo estamos resolviendo un problema (i + 1, j)
y la respuesta es C(i + 1, j)
. Si lo estamos, completamos la solución haciendo cambios para j - a_i
. Para hacer esto usando la menor cantidad de monedas posible, queremos resolver el problema (i, j - a_i)
. Arreglamos las cosas para que estos dos problemas ya están resueltos por nosotros y luego:
C(i, j) = C(i + 1, j) if a_i > j
= min(C(i + 1, j), 1 + C(i, j - a_i)) if a_i <= j
Ahora averiguar lo que los casos iniciales son y cómo se traduce esto en el idioma de su elección y usted debe ser bueno para ir.
Si quiere probar sus manos en otro problema interesante que requiere programación dinámica, mire el Proyecto Euler Problem 67.
Ayudando a un chico a resolver un problema de tarea no les convertirá repentinamente en un estudiante de A +. En algunos casos, podría ayudar a que el alumno "vea la luz" y se convierta en un joven y brillante desarrollador. Sin embargo, alguien que repite el comportamiento (no tratando de resolver los problemas por sí mismo) es más probable que sea alguien que nunca crece porque no se está desafiando a sí mismo. Se estrellarán y arderán miserablemente en algún momento, probablemente el día del examen. Al menos donde fui a la escuela, los exámenes eran una fracción tan grande de nuestras calificaciones que la tarea era efectivamente irrelevante (en un examen del curso fueron 100%). – jason