确定给定金额的变更组合

时间:2012-03-01 14:46:37

标签: algorithm

我的任务是使用蛮力编写算法来确定不同方式的数量,给定数量的相关变化组合。更改将使用以下硬币生产:便士(1美分),镍(5美分),角钱(10美分)和季度(25美分)。

e.g。

输入:16(表示更改为16美分)

输出:可以通过6种不同的方式生成,它们是:

  1. 16便士。
  2. 11便士,1镍
  3. 6便士,1角钱
  4. 6便士,2个镍币
  5. 1便士,3个镍币
  6. 1便士,1镍,1角钱
  7. 我的算法必须为指定的更改量生成所有可能的更改组合。


    我完全不知道如何开始这样的算法。让我前进的任何意见或见解都会很棒。

5 个答案:

答案 0 :(得分:4)

确定。让我解释一下蛮力算法的一个想法。我将在这里使用递归。

我们需要更改c美分。然后将c视为

c = p * PENNY + n * NICKEL + d * DIME + q * QUARTER

或简单地说,

c = ( p * 1 ) + ( n * 5 ) + ( d * 10 ) + ( q * 25 )

现在,您需要查看pndq等于c值的所有可能值。使用递归,每个p in [0, maximumPennies]遍历每个n in [0, maximumNickels]。对于每个n,请查看每个d in [0, maximumDimes]。对于每个d,请查看每个q in [0, maximumQuarters]

p in [0, maximumPennies] AND c >= p
  |
  +- n in [0, maximumNickels] AND c >= p + 5n
       |
       +- d in [0, maximumDimes] AND c >= p + 5n + 10d
            |
            +- q in [0, maximumQuarters] AND c >= p + 5n + 10d + 25q

对于这些步骤中的任何相等,您都可以找到解决方案。

答案 1 :(得分:3)

您可以通过将其划分为子问题来解决这些问题,然后更改问题并调整解决方案,从而开始考虑此问题。

在你的情况下,你可以首先尝试使用只有便士解决问题(当然只有一个明显的解决方案),然后看看镍和便士,看看那里的所有组合,依此类推。为了改善这一点,您可以重用算法中早期阶段的解决方案。

答案 2 :(得分:2)

好吧,如果你想要蛮力解决方案,你可以从一个非常幼稚的recursive approach开始。但为了提高效率,您需要dynamic programming approach

对于递归方法:

1. find out the number of ways you can make using penny only.
2. do the same using penny and nickel only. (this includes step 1 also)
3. the same using penny, nickel and dime only (including step 2).
4. using all the coins (with all previous steps).

第1步很简单,只有一种方法可以做到。

对于第2步,递归应该是这样的:

number of ways to make n cent using penny and nickel = 
    number of ways to make (n - [1 nickel]) using penny and nickel
    + number of ways to make n cent using penny only

第3步:

number of ways to make n cent using penny, nickel and dime = 
    number of ways to make (n - [1 dime]) using penny, nickel and dime
    + number of ways to make n cent using penny and nickel only

第4步类似。

有一点需要记住:你可以用一种方式赚取0美分(即使用零硬币),这是基本情况。

答案 3 :(得分:0)

尝试在此上使用递归。 您的函数应该采用两个参数 - 允许使用的最大值和剩余的支付金额(您需要第一个以避免重复)。 以这样的方式制作功能:如果它是一个简单的情况(例如1,5,10,你可以分别拿一分钱,镍,一角钱)打印琐碎的解决方案。同样对于每种情况,尝试取一个所有允许类型的硬币(例如,不大于允许的最大值)并继续递归。

希望这有帮助。

答案 4 :(得分:-1)

public class PrintAllCoinCombinations {


    static int findChange(int arr[], int index , int value, String str){

        if(value == 0){
            System.out.println(str);
            return 1;
        }
        if(index<0){
            return 0;
        }
        if(value<0){
            return 0;
        }

        int excl  = findChange(arr,index-1,value,str);

        str += " "+ arr[index];

        int incl = findChange(arr,index,value-arr[index],str);

        return incl + excl;

    }

    public static void main(String [] arg){
        int arr[] = {1,5,10,25};
        String s = "";
        int result = findChange(arr,3,16,s);
        System.out.println(result);
    }
}