in

Cambio de moneda | DP-7 – GeeksforGeeks

gfg 200x200 min

Dado un valor N, si queremos hacer un cambio por N centavos, y tenemos un suministro infinito de cada una de las monedas valoradas en S = {S1, S2, .., Sm}, ¿de cuántas formas podemos hacer el cambio? El orden de las monedas no importa.
Por ejemplo, para N = 4 y S = {1,2,3}, hay cuatro soluciones: {1,1,1,1}, {1,1,2}, {2,2}, {1, 3}. Por lo tanto, la salida debe ser 4. Para N = 10 y S = {2, 5, 3, 6}, hay cinco soluciones: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} y {5,5}. Entonces la salida debería ser 5.

1) Subestructura óptima
Para contar el número total de soluciones, podemos dividir todas las soluciones de conjuntos en dos conjuntos.
1) Soluciones que no contienen mth coin (o Sm).
2) Soluciones que contienen al menos un Sm.
Vamos a contar (S[], m, n) sea la función para contar el número de soluciones, entonces se puede escribir como la suma del recuento (S[], m-1, n) y contar (S[], m, n-Sm).
Por lo tanto, el problema tiene una propiedad de subestructura óptima ya que el problema se puede resolver utilizando soluciones a los subproblemas.

2) Subproblemas superpuestos
A continuación se muestra una implementación recursiva simple del problema Coin Change. La implementación simplemente sigue la estructura recursiva mencionada anteriormente.

3) Enfoque (algoritmo)

Mira, aquí cada moneda de una denominación determinada puede venir un número infinito de veces. (Repetición permitida), esto es lo que llamamos MOCHILA LIBRE. Tenemos 2 opciones para una moneda de una denominación particular, ya sea i) para incluir o ii) para excluir. Pero aquí, el proceso de inclusión no es solo una vez; podemos incluir cualquier denominación cualquier número de veces hasta que N

Básicamente, si estamos en s[m-1], podemos tomar tantas instancias de esa moneda (inclusión ilimitada), es decir contar (S, m, n – S[m-1] ) ; luego pasamos a s[m-2]. Después de pasar a s[m-2], no podemos retroceder y no podemos tomar decisiones por s[m-1] es decir contar (S, m-1, n).

Finalmente, como tenemos que encontrar el número total de formas, agregaremos estas 2 opciones posibles, es decir contar (S, m, n – S[m-1] ) + cuenta (S, m-1, n); cuál será nuestra respuesta requerida.

C ++

#include <bits/stdc++.h>

using namespace std;

int count(int S[], int m, int n)

{

    

    

    

    if (n == 0)

        return 1;

    

    

    

    if (n < 0)

        return 0;

    

    

    

    if (m <= 0 && n >= 1)

        return 0;

    

    

    return count(S, m - 1, n) +

           count(S, m, n - S[m - 1]);

}

int main()

{

    int i, j;

    int arr[] = { 1, 2, 3 };

    int m = sizeof(arr) / sizeof(arr[0]);

    

    cout << " " << count(arr, m, 4);

    

    return 0;

}

C

#include<stdio.h>

int count( int S[], int m, int n )

{

    

    

    if (n == 0)

        return 1;

    

    

    

    if (n < 0)

        return 0;

    

    

    

    if (m <=0 && n >= 1)

        return 0;

    

    

    return count( S, m - 1, n ) + count( S, m, n-S[m-1] );

}

int main()

{

    int i, j;

    int arr[] = {1, 2, 3};

    int m = sizeof(arr)/sizeof(arr[0]);

    printf("%d ", count(arr, m, 4));

    getchar();

    return 0;

}

Python3

def count(S, m, n ):

    

    

    if (n == 0):

        return 1

    

    

    if (n < 0):

        return 0;

    

    

    

    if (m <=0 and n >= 1):

        return 0

    

    

    return count( S, m - 1, n ) + count( S, m, n-S[m-1] );

arr = [1, 2, 3]

m = len(arr)

print(count(arr, m, 4))

C#

using System;

class GFG

{

    

    

    static int count( int []S, int m, int n )

    {

        

        

        if (n == 0)

            return 1;

        

        

        

        if (n < 0)

            return 0;

    

        

        

        

        if (m <=0 && n >= 1)

            return 0;

    

        

        

        return count( S, m - 1, n ) +

            count( S, m, n - S[m - 1] );

    }

    

    

    public static void Main()

    {

        

        int []arr = {1, 2, 3};

        int m = arr.Length;

        Console.Write( count(arr, m, 4));

        

        

    }

}

PHP

<?php

function coun($S, $m, $n)

{

    

    

    

    

    if ($n == 0)

        return 1;

    

    

    

    if ($n < 0)

        return 0;

    

    

    

    if ($m <= 0 && $n >= 1)

        return 0;

    

    

    return coun($S, $m - 1,$n ) +

           coun($S, $m, $n - $S[$m - 1] );

}

    

    $arr = array(1, 2, 3);

    $m = count($arr);

    echo coun($arr, $m, 4);

    

?>

Javascript

<script>

   

function count(S , m , n )

{

    

    

    if (n == 0)

        return 1;

    

    

    

    if (n < 0)

        return 0;

    

    

    

    if (m <=0 && n >= 1)

        return 0;

    

    

    return count( S, m - 1, n ) +

           count( S, m, n - S[m - 1] );

}

var arr = [1, 2, 3];

var m = arr.length;

document.write( count(arr, m, 4));

</script>

Cabe señalar que la función anterior calcula los mismos subproblemas una y otra vez. Consulte el siguiente árbol de recursividad para S = {1, 2, 3} yn = 5.

La función C ({1}, 3) se llama dos veces. Si dibujamos el árbol completo, podemos ver que hay muchos subproblemas que se llaman más de una vez.

C() --> count()
                             C({1,2,3}, 5)                     
                           /                 
                         /                                   
             C({1,2,3}, 2)                 C({1,2}, 5)
            /                             /               
           /                             /            
C({1,2,3}, -1)  C({1,2}, 2)        C({1,2}, 3)    C({1}, 5)
               /                 /                /     
             /                  /                /        
    C({1,2},0)  C({1},2)   C({1,2},1) C({1},3)    C({1}, 4)  C({}, 5)
                   /      /         /         /              
                  /      /        /          /         
                .      .  .     .   .     .   C({1}, 3) C({}, 4)
                                               /  
                                              /      
                                             .      .

Dado que se vuelven a llamar los mismos subproblemas, este problema tiene la propiedad Overlapping Subproblems. Entonces, el problema del cambio de moneda tiene ambas propiedades (ver esto y esto) de un problema de programación dinámica. Al igual que otros problemas típicos de programación dinámica (DP), los recálculos de los mismos subproblemas se pueden evitar construyendo una tabla de matriz temporal[][] de abajo hacia arriba.

Solución de programación dinámica

C ++

#include<bits/stdc++.h>

using namespace std;

int count( int S[], int m, int n )

{

    int i, j, x, y;

    

    

    

    

    int table[n + 1][m];

    

    

    

    for (i = 0; i < m; i++)

        table[0][i] = 1;

    

    

    for (i = 1; i < n + 1; i++)

    {

        for (j = 0; j < m; j++)

        {

            

            x = (i-S[j] >= 0) ? table[i - S[j]][j] : 0;

            

            y = (j >= 1) ? table[i][j - 1] : 0;

            

            table[i][j] = x + y;

        }

    }

    return table[n][m - 1];

}

int main()

{

    int arr[] = {1, 2, 3};

    int m = sizeof(arr)/sizeof(arr[0]);

    int n = 4;

    cout << count(arr, m, n);

    return 0;

}

C

#include<stdio.h>

int count( int S[], int m, int n )

{

    int i, j, x, y;

    

    

    

    int table[n+1][m];

   

    

    for (i=0; i<m; i++)

        table[0][i] = 1;

    

    

    for (i = 1; i < n+1; i++)

    {

        for (j = 0; j < m; j++)

        {

            

            x = (i-S[j] >= 0)? table[i - S[j]][j]: 0;

            

            y = (j >= 1)? table[i][j-1]: 0;

            

            table[i][j] = x + y;

        }

    }

    return table[n][m-1];

}

int main()

{

    int arr[] = {1, 2, 3};

    int m = sizeof(arr)/sizeof(arr[0]);

    int n = 4;

    printf(" %d ", count(arr, m, n));

    return 0;

}

Java

   

import java.util.Arrays;

class CoinChange

{

    static long countWays(int S[], int m, int n)

    {

        

        

        

        

        

        

        long[] table = new long[n+1];

        

        Arrays.fill(table, 0);  

        

        mesa[0] = 1;

        

        

        

        for (int i=0; i<m; i++)

            for (int j=S[i]; j<=n; j++)

                table[j] += table[j-S[i]];

        return table[n];

    }

    

    public static void main(String args[])

    {

        int arr[] = {1, 2, 3};

        int m = arr.length;

        int n = 4;

        System.out.println(countWays(arr, m, n));

    }

}

Pitón

def count(S, m, n):

    

    

    

    table = [[0 for x in range(m)] for x in range(n+1)]

    

    for i in range(m):

        mesa[0][i] = 1

    

    for i in range(1, n+1):

        for j in range(m):

            

            x = mesa[i - S[j]][j] if i-S[j] >= 0 else 0

            

            y = mesa[i][j-1] if j >= 1 else 0

            

            table[i][j] = x + y

    return mesa[n][m-1]

arr = [1, 2, 3]

m = len(arr)

n = 4

print(count(arr, m, n))

C#

using System;

class GFG

{

    static long countWays(int []S, int m, int n)

    {

        

        

        

        

        

        

        int[] table = new int[n+1];

        

        for(int i = 0; i < table.Length; i++)

        {

            table[i] = 0;

        }

        

        table[0] = 1;

        

        

        

        for (int i = 0; i < m; i++)

            for (int j = S[i]; j <= n; j++)

                table[j] += table[j - S[i]];

        return table[n];

    }

    

    public static void Main()

    {

        int []arr = {1, 2, 3};

        int m = arr.Length;

        int n = 4;

        Console.Write(countWays(arr, m, n));

    }

}

PHP

<?php

function count1($S, $m, $n)

{

    

    

    

    

    

    $table;

    for ($i = 0; $i < $n + 1; $i++)

    for ($j = 0; $j < $m; $j++)

        $table[$i][$j] = 0;

    

    

    

    for ($i = 0; $i < $m; $i++)

        $table[0][$i] = 1;

    

    

    for ($i = 1; $i < $n + 1; $i++)

    {

        for ($j = 0; $j < $m; $j++)

        {

            

            

            $x = ($i-$S[$j] > = 0)?

                  $table[$i - $S[$j]][$j] : 0;

            

            

            $y = ($j >= 1) ?

                  $table[$i][$j - 1] : 0;

            

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

apple touch icon@2

linux – ¿Cómo hago grep de forma recursiva?

edit

Galón vs Litro – Diferencia y Comparación