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.归并排序是