递归解决换零钱问题--回顾总结之递归的表达能力

前面为了保持叙述的流畅,没有做太多的引申,把总结推迟到了后面。

补上一些总结,以防止出现“下面呢?下面没有了”的尴尬。

方向性问题


虽然题目在一开始就暗示了这一点,但首先,我们还是要问,它能用递归解决吗?

有点怀疑精神是好的,既要低头走路,更要抬头看路,以防止发生方向性错误,导致缘木求鱼的后果。

说这个问题能用递归解决,这种信心或者判断的依据来自于哪呢?

有人可能知道了,换零钱这个问题在《计算机程序的构造和解释》(SICP:Structure and Interpretation of Computer Programs)一书有这个例子,而在书上是用递归来解决的。

相似性

在前面的有趣的递归(Recursion),一些直观的示例中,展示了一些递归的直观的示例,还提到了相似性这一点,递归的东西总是带着点相似性;反之,如果我们能发现相似性,那么它也很可能是递归。

以换零钱为例,100可以换成50+20+20+10,单独拿出50也可换成20+20+10,你能隐约感觉到一些相似,尽管还不能明确的说出来。

直观以及与此相关的直觉常常能给我们指明方向,尽管这种感觉带有很大的主观性及不确定性,但当我们还无法确定问题的方向时,它也许能给我们带来一丝线索。

循环

在前面的经典递归分析说到,循环(迭代)总是可以用递归来解决,因为递归其实也就是在方法层面的循环。那么这个问题能用循环解决吗?

作为计算机科学中的一个伟大远见(洞察力)(great insight)之一的Boehm and Jacopini’s Insight是这样说的:

Only three rules of grammar are needed to combine any set of basic instructions (verbs) into more complex ones:

只须三种语法规则去组合那些基本的命令就可表述那些更加复杂的过程。

它们是:

  1. 顺序(sequence)
  2. 分支(selection or choice)
  3. 循环(repetition or looping)

考察换零钱问题,如果不能用循环解决的话,那么用程序去解决这个问题可能就没什么优势了。

试想如果仅用顺序及分支,而所谓分支不过就是枚举各种情况,这样即便能写出程序,恐怕也是极其臃肿,而且可能只是特定于某个问题,不具有普适性。

所以,如果断定换零钱问题存在循环解法,那么它也就一定能用递归解决了。L. Peter Deutsch有句名言:

To iterate is human, to recurse divine.(迭代者人,递归者神) 

所有的程序都可以用三种结构表示出来,递归本身是一种循环手段,在递归体的内部又可以包含顺序与分支的情况,从这个意义上说,事情其实已经是很明朗的了,递归方式并不存在什么局限性。人们很多时候并没有采用它一者可能是习惯问题,二者则是效率问题。

广义角度

尽管我们可能没有意识到,很多的问题都可以用递归去表达的。比如,秦始皇统一六国使用的远交近攻手段也可写成递归方式:

远交近攻(未统一地区) {
	如果(未统一地区.还有离我较远的国家()) {
		交往之(未统一地区.离我较远的国家());
		消灭之(未统一地区.离我较近的国家());

		// 递归,把原来“离我较远的国家”当成新的“未统一地区”
		远交近攻(未统一地区.离我较远的国家());
	} 否则 {
		消灭之(未统一地区.离我较近的国家());
		// 达成统一大业
	}
}

以下图片展示了这一过程:(当然了,与真实的历史过程是有很大区别的,仅作演示)

是不是觉得有点扯谈呢?还是那句话,只要是循环的重复的过程,总是可以用递归来表达的。

时间: 2024-11-08 12:57:10

递归解决换零钱问题--回顾总结之递归的表达能力的相关文章

透析递归应用-换零钱

题目源于<SICP>,这里做一下调整,如下: 给了面值为50元.20元.10元.5元.1元的五种零钱若干,思考把面值100元人民币换成零钱一共有多少种方式? SICP给出的递归算法思想如下: 将总数为a的现金换成n种不同面值的不同方式的数目等于: 将现金a换成除了第一种面值之外的所有其他面值的不同方式数目,加上 将现金a-d换成所有种类的面值的不同方式数目,其中d是第一种面值的钱币 下面有解释到,递归的思想是要将问题归约到对更少现金数或更多种类面值钱币的同一个问题.有如下的约定: 如果a==0

递归练习之换零钱方式统计(c/c++)

/********************************************************************************* Copyright (C), 1988-1999, drvivermonkey. Co., Ltd. File name: Author: Driver Monkey Version: Mail:[email protected] qq:196568501 Date: 2014.04.02 Description: 递归练习之换零钱

关于SICP 1.2.2节中的换零钱方式的统计研究及其迭代实现。

关于SICP 1.2.2节中的换零钱方式的统计研究及其迭代实现 最近开始看sicp(计算机程序的构造和解释)一书,此书竟然是mit的计算机入门教材,不得不令人感叹天朝大学教育与真正一流大学的差距之大..我们在学习c语言的时候,人家已经开始学习剥离具体语言之外的编程思想了..扯远了,说回正题 sicp在1.2.2节中提到了一个有意思的换零钱实例: 将1美元(100美分)换成半美元,1/4美元,10美分,5美分,1美分的零钱,一共有多少种换法? 初看感觉有点无从下手,脑子里想的是各种排列组合,一片混

SDUT3145:Integer division 1(换零钱背包)

题目:传送门 题目描述 整数划分是一个非常经典的数学问题. 所谓整数划分,是指把一个正整数n写成为n=m1+m2+...+mi的形式,其中mi为正整数,并且1<=mi<=n,此时,{m1, m2, ..., mi}为n的一个划分.如果{m1, m2, ..., mi}中的最大值不超过m,即max{m1, m2, ..., mi}<=m,那么我们称之为整数n的一个m划分. 现在给出你正整数n和m,请你输出n的m划分的数量. 例如,当n=4时,有5个划分,即{4}, {3,1}, {2,2}

动态规划题目(一)——换零钱

动态规划题目(一)--换零钱 1. 题目描述 想兑换100元钱,有1,2,5,10四种钱,问总共有多少兑换方法. 下面提供两种实现方式,其中代码注释的很清楚. 关于动态规划的基本原理,参考: http://www.cnblogs.com/sdjl/articles/1274312.html 2. 递归解法 //动态规划 #include<iostream> using namespace std; const int N = 100; int dimes[] = {1, 2, 5, 10};

贪心算法换零钱(java)

贪心算法思想 贪心算法总是做出在当前看来做好的选择.也就是说贪心算法并不从整体最后考虑,他做出的选择只是局部最优选择.他所做出的仅是在某种意义上的局部最优解.贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解. 1.算法思路 贪心算法是一种不追求最优解,只希望得到较为满意解的方法.贪心算法一般可以快速得到满意的解,因为它省去了为找最优姐要穷尽所有肯呢个而必须耗费大量时间.贪婪(心)算法是一种改进了的分级处理方法.其核心是根据题意选取一种

汉诺塔递归解决方法经典分析

一位法国数学家曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面.僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔.庙宇和众生也都将同归于尽. 虽然这只是一个传说,但也给我们提出了一个问题,

小P的故事——神奇的换零钱&amp;&amp;人活着系列之平方数

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2777&cid=1219 这题不会,看了别人的代码 #include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> using namespace std; int dp[32770]; int main() { int n,i,j; int w[4]= {

java数据结构与算法之递归思维(让我们更通俗地理解递归)

[版权申明]转载请注明出处(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53452971 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) java数据结构与算法之栈(Stack)设计与实现 j