再探找零钱的个数

http://www.cnblogs.com/hansongjiang/p/3810825.html上回了个博客,是关于1块钱,用 1,2,5分等硬币找钱,共有多种,当时是用搜索出所以可能的组合方式找的,当时参考的博客没看懂。也没仔细想。

无意中看到http://www.ibm.com/developerworks/cn/java/j-lo-funinscala1/,这篇文章后,又重新开始思考,

int count( int S[], int m, int n )
{
    // 如果n为0,就找到了一个方案
    if (n == 0)
        return 1;
    if (n < 0)
        return 0;
    // 没有硬币可用了,也返回0
    if (m <=0 )
        return 0;
    // 按照上面的递归函数
    return count( S, m - 1, n ) + count( S, m, n-S[m-1] );
}

递归的思考方式在数学中就是归纳,所有有一个归纳方程,对于归纳方程要有初始化的值,列如:

整数的定义  1是整数(k=1)

               f(k+1)=f(k)+1;(K>1)

  于是写成函数是什么呢?

1 int fun(int k)
2 {
3 if(k==1) return k;
4 else return f(k-1)+1;
}

很多情况,问题不是那么简单。首先考虑问题与那些因素有关,也就是当前的状态是什么.状态是用参数来表示的。

对于找钱问题我的状态是从(1块钱 ,3种硬币),(  0元钱,n种硬币);只要钱最后为0,就可以了。

状态-------(选择了硬币)----另一种状态  

当前钱数 money,当前硬币总数n,数组为硬币的价值,s[];fun(money,n,s)

选择硬币: 可以选择第n中硬币,也可以不选,如果当前选择了这个硬币,下次可以再选,如果没选,下次就不能再选了。其实这种搜索把每种可能都枚举出来,对于1快钱,5分的硬币,可以选择0到20个

int count(int S[],int m,int n)
{
 if(m==0)  return 1; //找到一种解决方案

if(m<0) return 0;//没有找到
if(m>0&&n==0) return 0; 有钱没找,但是没有硬币可找
//下面的就是 m>0 ,n>0
return  count(S,m-s[n],n)  +count(S,m,n-1);
  //第一个是选了第n个硬币,第二个是不选,并且永远不会选。





}

到此为止了?上回还个问题,就是硬币是否是无数个,还是都只有一个的问题,如果都只有一个呢?

加入只有{1,2,5}那么这个集合有2的n次方种可能,可以搜索,那么照着刚才的思维来思考呢?

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

选择: 钱变成 m-s[n],物品变为n-1

不选择:钱变成 m,物品还是 N-1

好了写代码吧:

int  count(int S[],int m,int n)
{
if(m==0) return 1;
if(m<0 return 0;
if(n==0) return  0;

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



}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.首先可以改写一下排序?

a.插入,选择等排序都是递归的,我们改为循环试试。

b.归并排序是

 

 

 

 

posted @ 2014-07-02 14:48  hansongjiang8  阅读(182)  评论(0编辑  收藏  举报