Está en la página 1de 7

Problema de las monedas con programación dinámica

Para el problema de las monedas con programación dinámica se necesita crear un algoritmo
que permita a una máquina expendedora devolver el cambio mediante el menor número de
monedas posible. Mediante la programación dinámica se solucionará el caso en el que el número de
monedas de cada tipo es ilimitado. En el problema de las monedas mediante el algoritmo voraz
el que el número de monedas es ilimitado.

Descripción

Supongamos que se tienen monedas de valor 1, 4 y 6 y que se debe devolver una cantidad
correspondiente al valor 8. Siguiendo el método de la programación dinámica, se rellenará una
tabla con las filas correspondientes a cada valor para las monedas y las columnas con valores desde
el 1 hasta el 8. Cada posición (i, j) de la tabla nos indica el número mínimo de monedas requeridas
para devolver la cantidad j con monedas con valor menor o igual al de i:

____ 1 2 3 4 5 6 7 8
m1=1 1 2 3 4 5 6 7 8
m2=4 1 2 3 1 2 3 4 2
m3=6 1 2 3 1 2 1 2 2

Ejemplo para la posición i = 2 y j = 7, se requiere una moneda tipo 2 con valor 4 y tres monedas de
tipo 1 con valor uno, por lo tanto en la tabla el número de monedas en la posición (2,7) sera 1 + 3 =
4.

Algoritmo

1. Para cada casilla de la tabla hacer:


2. Si el valor de la moneda actual es mayor que la cantidad, se paga con el resto de monedas, es
decir, se toma el resultado de la casilla superior.
3. Si el valor de la moneda actual es menor o igual que la cantidad, se toma el mínimo entre:
1. Pagar con el resto de monedas, tomando el resultado de la casilla superior.
2. Pagar con una moneda del tipo actual y el resto con el resultado que se hubiera obtenido al pagar
la cantidad actual a la que se le ha restado el valor de la moneda actual.
4. Tomar como resultado el valor de la última celda.

Pseudocódigo

Solucionemos este problema de programación dinámica en un pseudocódigo.

Como parámetros de entrada, la función toma C, que corresponde con la cantidad a devolver, y un
vector M de monedas, que almacena el valor de cada tipo. Devuelve num, el número de monedas
necesarias para realizar la devolución.

fun cambio (C: nat; M[1..n] de nat) dev num: nat


var
T[0..n][0..C] de nat
begin
T[0][1..C] := \infty;
T[1..n][0] := 0;
para i := 1 hasta n hacer
para j := 1 hasta C hacer
si M[i] > j entonces T[i, j] := T[i-1, j]
si no
T[i, j] := min {T[i-1, j], T[i, j-M[i] ] + 1 }
fsi
fpara
fpara
num := T[n, C]
ffun

Código Java

Solucionemos este problema de programación dinámica en un código Java:

public int Minima_devolucion(int cantidad_devuelta, int[] monedas){


//Creamos la matriz de devoluciones
int[][] matriz_cambio = new int[monedas.length+1]
[cantidad_devuelta+1];

//Rellenamos la 1ª columna de ceros


for(int i = 0; i < monedas.length; i++)
matriz_cambio[i][0] = 0;

//La 1ª fila menos la 1ª columna un número alto


for(int j = 1; j <= cantidad_devuelta; j++)
matriz_cambio[0][j] = 999999;

for(int i = 1; i <= monedas.length ; i++)


for(int j = 1; j <= cantidad_devuelta; j++){
if(monedas[i-1] > j ){
//Si la moneda es superior a la cantidad a devolver
matriz_cambio[i][j] = matriz_cambio[i-1][j];
}else{
//Si la moneda no es superior a la cantidad a devolver

//Calcular cual es el mínimo de estas dos posiciones


int minimo = 0; //Guardaremos aquí el mínimo

if(matriz_cambio[i-1][j] < matriz_cambio[i][j - monedas[i-1]] + 1){


minimo = matriz_cambio[i-1][j];
}else{
minimo = matriz_cambio[i][j - monedas[i-1]] + 1;
}
//Guardamos mínimo
matriz_cambio[i][j] = minimo;
}
}

return matriz_cambio[monedas.length][cantidad_devuelta];
}

También podría gustarte