Динамическое программирование - внесение изменений - PullRequest
6 голосов
/ 07 ноября 2011

У меня проблемы с выяснением моего последнего раздела кода для задачи динамического изменения монет.Я включил код ниже.

Я не могу выяснить последние else.Должен ли я просто использовать жадный алгоритм в этой точке или я могу рассчитать ответ по значениям уже в таблице?Я работал тяжело, пытаясь понять эту проблему, и я думаю, что я довольно близко.Метод находит минимальное количество монет, необходимое для внесения определенной суммы изменений, путем создания таблицы и использования результатов, хранящихся в таблице, для решения более крупной проблемы без использования рекурсии.

public static int minCoins(int[] denom, int targetAmount){
    int denomPosition; // Position in denom[] where the first spot
                       // is the largest coin and includes every coin
                       // smaller.
    int currentAmount; // The Amount of money that needs to be made
                       // remainingAmount <= initalAmount
    int[][] table = new int[denom.length][targetAmount+1];
    for(denomPosition = denom.length-1 ; denomPosition >= 0 ; denomPosition--) {
        for(currentAmount = 0 ; currentAmount <= targetAmount ; currentAmount++){
            if (denomPosition == denom.length-1){
                table[denomPosition][currentAmount] = 
                     currentAmount/denom[denomPosition];
            }
            else if (currentAmount<denom[denomPosition]){
                table[denomPosition][currentAmount] = 
                     table[denomPosition+1][currentAmount];
            }
            else{           
                table[denomPosition][currentAmount] = 
                     table[denomPosition+1][currentAmount]-
                     table[denomPosition][denom[denomPosition]]-1;
            }
        }
    }
    return table[0][targetAmount];
}

Ответы [ 4 ]

2 голосов
/ 07 ноября 2011

Вам не нужно переключаться на жадный алгоритм для решения проблемы замены монет, вы можете решить его с помощью алгоритма динамического программирования. Например, вот так:

public int minChange(int[] denom, int targetAmount) {

    int actualAmount;
    int m = denom.length+1;
    int n = targetAmount + 1;
    int inf = Integer.MAX_VALUE-1;

    int[][] table = new int[m][n];
    for (int j = 1; j < n; j++)
        table[0][j] = inf;

    for (int denomPosition = 1; denomPosition < m; denomPosition++) {
        for (int currentAmount = 1; currentAmount < n; currentAmount++) {
            if (currentAmount - denom[denomPosition-1] >= 0)
                actualAmount = table[denomPosition][currentAmount - denom[denomPosition-1]];
            else
                actualAmount = inf;
            table[denomPosition][currentAmount] = Math.min(table[denomPosition-1][currentAmount], 1 + actualAmount);
        }
    }

    return table[m-1][n-1];

}
1 голос
/ 15 сентября 2013
//this works perfectly ...

 public int minChange(int[] denom, int targetAmount) 
    {

    int actualAmount;
    int m = denom.length+1;
    int n = targetAmount + 1;
    int inf = Integer.MAX_VALUE-1;

    int[][] table = new int[m][n];
    for (int j = 1; j < n; j++)
        table[0][j] = inf;

    for (int i = 1; i < m; i++) //i denotes denominationIndex
    {
        for (int j = 1; j < n; j++) //j denotes current Amount
        {
            if (j - denom[i-1] >= 0)//take this denomination value and subtract this value from Current amount

                table[i][j] = Math.min(table[i-1][j], 1 + table[i][j - denom[i-1]]);

            else
                table[i][j] = table[i-1][j];

        }
    }




    //display array
        System.out.println("----------------Displaying the 2-D Matrix(denominations and amount)----------------");
        for (int i = 0; i < m; i++) 
        {
            System.out.println("   ");
            for (int j = 0; j < n; j++) 
            {
                System.out.print("  "+table[i][j]);

            }
            System.out.println("   ");
        }

    return table[m-1][n-1];

}
0 голосов
/ 05 января 2013

Это на самом деле правильная версия этого алгоритма.

public static int minChange(int[] denom, int targetAmount) {
    int actualAmount;
    int m = denom.length + 1;
    int n = targetAmount + 1;
    int inf = Integer.MAX_VALUE - 1;

    int[][] table = new int[m][n];
    for(int i = 0; i< m; ++i) {
        for (int j = 1; j < n; j++) {
            table[i][j] = inf;
        }
    }

    for (int denomPosition = 1; denomPosition < m; denomPosition++) {
        for (int currentAmount = 1; currentAmount < n; currentAmount++) {
            if (denom[denomPosition-1] <= currentAmount) {
                // take
                actualAmount = table[denomPosition][currentAmount - denom[denomPosition-1]];
            }
            else {
                actualAmount = inf;
            }                                              // do not take
            table[denomPosition][currentAmount] = Math.min(table[denomPosition-1][currentAmount], 1 + actualAmount);
        }
    }

    return table[m-1][n-1];
}
0 голосов
/ 07 ноября 2011

Вы над этим думаете? Если бы мы пытались дать 68 центов, используя монеты США…

Будет ли "denom" {25, 10, 5, 1}?

И не будет ли ответ «2 четверти, 1 цент, 1 никель и 3 копейки» = 2 + 1 + 1 + 3 = 7 ’ Таким образом, функция должна возвращать значение 7. Верно?

...