递归计算硬币支付组合

时间:2013-12-22 15:59:41

标签: java algorithm recursion

我正在尝试实施递归算法,该算法计算给定金额的所有可能的付款组合。我根本没有太多的递归经验,所以我很感激你的一些帮助。

可用欧元硬币:1美分,2美分,5美分,10美分,20美分,50美分,1欧元,2欧元。

所以我正在寻找函数的绝对值,该函数给出了给定金额的8个硬币的线性组合。

所有这些线性组合的绝对值或集合可以分成两个不相交的子集,即M1,它是不包含硬币n的所有线性组合的集合,以及其中硬币n至少出现一次的子集M2每个线性组合,这相当于以下内容:http://imgur.com/1TVv8OJ

为了说明这一点,这里有一个5美分的例子,其中有4种不同的支付选项,即:5个1美分硬币,2个2美分硬币和1个1美分硬币,1个2美分硬币+三个1美分硬币,一个5美分硬币。

这是我在Java中实现的:

public class Coins {


static int[] c = { 1, 2, 5, 10, 20, 50, 100, 200};
static long M1 = 0;


public static long pay ( int m)
{
    int n = c.length;
    long M = pay(m, n);
    return M;
}

private static long pay( int m, int n)
{

    if ( n == 1)
    {   
        return 1;
    }
    if ( m == 0)
        return 1;
    if ( m < 0)
        return 0;
    M1 += pay(m, n - 1) + pay(m - c[n-1], n);
    return M1;
}

public static void main(String[] args) {
    int m = 6;
    long norm = pay(m);
    System.out.println(norm);
}
}

这个实现并没有给我正确的解决方案,我不确定它为什么没有或它在做什么。我尝试使用print语句,对于m = 6的情况,给我中间结果:

count = 1 m= 6 n= 8 M1= 0

count = 3 m= 6 n= 7 M1= 0

count = 5 m= 6 n= 6 M1= 0

count = 7 m= 6 n= 5 M1= 0

count = 9 m= 6 n= 4 M1= 0

count = 11 m= 6 n= 3 M1= 0

count = 13 m= 6 n= 2 M1= 0

count = 15 m= 6 n= 1 M1= 0

count = 16 m= 4 n= 2 M1= 0

count = 18 m= 4 n= 1 M1= 0

count = 19 m= 2 n= 2 M1= 0

count = 21 m= 2 n= 1 M1= 0

count = 22 m= 0 n= 2 M1= 0

count = 23 m= 1 n= 3 M1= 4

count = 25 m= 1 n= 2 M1= 4

count = 27 m= 1 n= 1 M1= 4

count = 28 m= -1 n= 2 M1= 4

count = 29 m= -4 n= 3 M1= 5

count = 30 m= -4 n= 4 M1= 13

count = 31 m= -14 n= 5 M1= 13

count = 32 m= -44 n= 6 M1= 13

count = 33 m= -94 n= 7 M1= 13

count = 34 m= -194 n= 8 M1= 13

现在它实际上确实正确计算,如果你要添加m=0n=1的情况,你会得到正确的解决方案,但它以某种方式获得结果13.任何人都可以告诉我这里发生了什么?为什么我的实现结果是13而不是5?

1 个答案:

答案 0 :(得分:0)

更改

M1 += pay(m, n - 1) + pay(m - c[n-1], n);

M1 = pay(m, n - 1) + pay(m - c[n-1], n);

M1是它下面2个分支的总和。

每个递归调用计算其子分支的M1并将结果返回给其父分支。