题目:《程序员面试金典(第5版)》P232
给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示方法。
提示:这是个递归问题,要找出如何利用子问题的答案进行计算。
int MakeChangeCore(int n,int denom)
{
int next_denom=0;
switch(denom)
{
case 25:
next_denom=10;
break;
case 10:
next_denom=5;
break;
case 5:
next_denom=1;
break;
case 1:
return 1;
}
int res=0;
for(int i=0;i*denom<=n;i++)
res+=MakeChangeCore(n-i*denom,next_denom);
return res;
}
int MakeChange(int n)
{
if(n<=0)
return -1;
return MakeChangeCore(n,25);
}
从币值大的硬币开始,每次取i个(i乘以币值要小于等于n), 然后接着去取币值比它小的硬币,这时就是它的一个子问题了,递归调用。 具体来怎么来理解这个事呢?这样,比如我要凑100分,那我先从25分开始, 我先取0个25分,然后递归调用去凑100分;再然后我取1个25分,然后递归调用去凑100-25 =75分;接着我取2个25分,递归调用去凑100-25*2=50分……这些取了若干个 25分硬币然后再去递归调用,取的就是10分硬币了。一直这样操作下去,我们就会得到, 由若干个25,若干个10分,若干个5分和若干个1分组成的100分,而且, 这里面每种币值的数量都可以为0。