coins

=Problema clásico de monedas=

Dado un conjunto de monedas con sus respectivos valores, ¿cuál es el mínimo número de monedas que se requieren para pagar cierta cantidad?

Ejemplo
Dadas las monedas Sudafricanas (1c, 2c, 5c, 10c, 20c, 50c, R1, R2 y R5), ¿cuántas monedas necesito para pagar R9.23?

Resolviendo el problema usando el enfoque ávido, es decir tomando la máxima cantidad de monedas de mayor valor siempre que sea posible, tenemos que:


 * = Resto   ||= Tomamos    ||
 * = R9.23 ||= R5 ||
 * = R4.23 ||= R2 ||
 * = R2.23 ||= R2 ||
 * = 23c ||= 20c ||
 * = 3c ||= 2c ||
 * = 1c ||= 1c ||
 * = 0 ||= - ||

Sabemos que un algoritmo voráz no siempre nos proporciona el resultado óptimo, por lo que es mejor emplear la solución mediante programación dinámica, la cuál nos asegura siempre el óptimo local para generar una solución óptima global.

Planteamiento de la solución
Si sabemos que podemos obtener el valor **v** con **C** monedas, entonces sabemos que para cada moneda **coin[i]** podemos obtener el valor (**v**+**coin[i]**) con un número (**C+1**) de monedas.

Lo que haremos es tomar la solución de un subproblema (el número de monedas necesarias para **v**) y usarla para solucionar los problemas más grandes (el número de monedas requeridas para (**v**+**coin[i]**)). Así que, de esta manera evitamos el recálculo de subproblemas. Posteriormente podemos usar las nuevas soluciones para resolver problemas aún más grandes (un valor de **v** mayor) hasta que finalmente se alcance la solución que requiere el problema, es decir, el número de monedas para **v** cantidad.

Inicialización : Explorar los casos pequeños
Empezamos por el caso base, es decir, con el problema del que ya conocemos la solución. Sabemos que podemos obtener el valor **v=0** con 0 monedas.

Solución del Problema usando subproblemas :P
Creamos un arreglo llamado **count**. El valor de **count[i]** representa el número mínimo de monedas necesarias para obtener el valor **i**. Establecemos **count[0]=0** (inicialización) y para todos los demás valores de **i** con un valor infinito.

Supongamos que tenemos 3 monedas, de valores 1c, 4c y 5c, ¿cúal es el mínimo de monedas que necesito para obtener 8c?


 * = 0 ||= 1 ||= 2 ||= 3 ||= 4 ||= 5 ||= 6 ||= 7 ||= 8 ||
 * = **0** ||= INF ||= INF ||= INF ||= INF ||= INF ||= INF ||= INF ||= INF ||

Iniciamos con 0. El valor de las monedas es 1,4 y 5. Por lo que para obtener estás cantidas solo necesitamos 1 moneda.


 * = 0 ||= 1 ||= 2 ||= 3 ||= 4 ||= 5 ||= 6 ||= 7 ||= 8 ||
 * = 0 ||= **1** ||= INF ||= INF ||= **1** ||= **1** ||= INF ||= INF ||= INF ||

Luego nos movemos al índice 1 y establecemos los elementos (1+1), (1+4) y (5+1) a (1+1). Pero existe un problema. Establecemos el 5o elemento con 2 monedas, pero como ya sabemos que podemos obtener los 5c con 1 sola moneda, cada vez que queramos modificar un elemento, necesitaremos verificar si la nueva solución es **mejor** que la anterior. El nuevo arreglo quedaría como sigue:


 * = 0 ||= 1 ||= 2 ||= 3 ||= 4 ||= 5 ||= 6 ||= 7 ||= 8 ||
 * = 0 ||= 1 ||= **2** ||= INF ||= 1 ||= //1// ||= **2** ||= INF ||= INF ||

Continuamos con este proceso, moviéndonos de izquierda a derecha hasta llegar al final:


 * = 0 ||= 1 ||= 2 ||= 3 ||= 4 ||= 5 ||= 6 ||= 7 ||= 8 ||= 9 ||
 * = 0 ||= 1 ||= 2 ||= 3 ||= 1 ||= 1 ||= 2 ||= 3 ||= 2 ||= 2 ||

Al final, obtenemos la solución el último elemento del arreglo (**count[8]**), el cuál es 2 como se esperaba (2 monedas de 4c).

Implementación en C++ :D
code format="cpp" //2768. Making Change TJU
 * 1) include
 * 2) define MAX_COINS 11
 * 3) define MAX_CENTS 1002
 * 4) define INF 0x0FFFFFFF

main{

int monedas[MAX_COINS]; int cambio[MAX_CENTS];   //vector solución int i,j,k, c,n ; while (scanf ("%d %d",&n,&c)==2){ monedas[0]=0; //inicializacion for (i=1; i<=n; i++) cambio[i] = INF; //read the coins for (i=0; in) continue; if (cambio[i]+1 < cambio[k]) cambio[k]=cambio[i]+1; }       }        printf ("%d\n",cambio[n]);

} }

code [|english version]