从1元、2元和5元的钞票和等于100元的算法问题谈到递归
2013-11-06 13:07
176 查看
引入
一直以来,递归思想成为不少新手的拦路虎。同样作为一个新手,我希望这篇文章可以从新手
的角度出发,走入递归。
如本文标题,相信不少人碰到过这个问题:
“现有面值为1元、2元和5元的钞票(假设每种钞票都足够多),从这些钞票中取出任意张数使
其总面值为100元,问有多少种取法?“
我们将从这个问题入手,逐步深入。
基本思路
本文我们要学习递归思想,因此对其他解法不作解释。一:先简化题目
将题中100元改成10元,即”现有面值为1元、2元和5元的钞票(假设每种钞票都足够多),从这些
钞票中取出任意张数使其总面值为10元,问有多少种取法“
以便于我们具体分析;
二:思路(希望大家可以跟着我的思路走)
基本规则: 1、每次只取一张钞票,面额小的优先。2、当已取钞票总额等于或超过10,则停止取钞,进行相应的判断后选择下一步的策略。
3、每次取出的面值必须比放回的钞票大。
4、每次取的面值必须大于或等于已取的面值。
现在我们开始去钞票,根据规则1,每次只取一张,我们从面额最小的开始取(面值小优先):
第一张:取1元;
第二张:取1元;
第三张:取1元;
.
.
.
第九张:取1元;
第十张:取1元;
此时已取钞票总额为10元,根据规则2,停止取钞,进行判断。(11111 11111)
1.我们发现手里的钞票总额刚好为10,取法数N变为1;
2.然后我们将最后(即第十张)取出的那张1元钞票放回未取钞票中,根据规则3,选择
一张面额为2的钞票放入手中;
此时已取钞票总额为11元,根据规则2,停止取钞,进行判断。(11111 11112)
1.我们发现手里的钞票总额为11,取法数N不变;
2.然后我们将最后取出的那张2元钞票放回未取钞票中,根据规则3,选择一张面额为5的
钞票放入手中;
此时已取钞票总额为14元,根据规则2,停止取钞,进行判断。(11111 11115)
1.我们发现手里的钞票总额为14,取法数N不变;
2.然后我们将最后取出的那张5元钞票放回未取钞票中,并且此时已没有比5面值更大的
钞票选择,因此我们的策略是:将此刻手中的最后取出(即第九张)的那张1元钞票放回
未取钞票中,根据规则3,再选择一张面额为2的钞票放入手中;
此时已取钞票总额为10元,根据规则2,停止取钞,进行判断。(11111 1112)
1.我们发现手里的钞票总额为10,取法数N变为2;
2.然后我们将最后取出的那张2元钞票放回未取钞票中,根据规则3,再选择一张面额为5
的钞票放入手中;
此时已取钞票总额为13元,根据规则2,停止取钞,进行判断。(11111 1115)
1.我们发现手里的钞票总额为13,取法数N不变;
2.然后我们将最后取出的那张5元钞票放回未取钞票中,并且此时已没有比5面值更大的
钞票选择,因此我们的策略是:将此刻手中的最后取出(即第八张)的那张1元钞票放回
未取钞票中,根据规则3,再选择一张面额为2的钞票放入手中;
此时已取钞票总额为9,根据规则4,因此取出一张面额为2的钞票。
此时已取钞票总额为11元,根据规则2,停止取钞,进行判断。(11111 11122)
1.我们发现手里的钞票总额为11,取法数N不变;
2.然后我们将最后取出的那张2元钞票放回未取钞票中,根据规则3,再选择一张
面额为5的钞票放入手中;
此时已取钞票总额为14元,根据规则2,停止取钞,进行判断。(11111 11125)
1.我们发现手里的钞票总额为11,取法数N不变;
2.然后我们将最后取出的那张5元钞票放回未取钞票中,并且此时已没有比5面值更大的
钞票选择,因此我们的策略是:将此刻手中的最后取出那张2元钞票放回未取钞票中,
根据规则3,再选择一张面额为5的钞票放入手中;
此时已取钞票总额为12,根据规则2,停止取钞,进行判断。(11111 115)
1.我们发现手里的钞票总额为12,取法数N不变;
2.然后我们将最后取出的那张5元钞票放回未取钞票中,并且此时已没有比5面值更大的
钞票选择,因此我们的策略是:将此刻手中的最后取出那张(第七张)1元钞票放回
未取钞票中,根据规则3,再选择一张面额为2的钞票放入手中;
此时已取钞票总额8,根据规则4,因此取出一张面额为2的钞票。
此时已取钞票总额为10元,根据规则2,停止取钞,进行判断。(11111 122)
1.我们发现手里的钞票总额为10,取法数N变为3;
2.然后我们将最后取出的那张2元钞票放回未取钞票中,根据规则3,再选择一张
面额为5的钞票放入手中;
(以此类推)
.
.
整个过程,手中钞票的变化过程如下
现有面值为1元、2元和5元的钞票(假设每种钞票都足够多),从这些钞票中取出
任意张数使其总面值为10元,问有多少种取法?N=10
以下为源码:
#include <stdio.h> int num=0; void zuhe(int min,int sum) { int i; if(sum==10) num++; if(sum>10) return; for(i=min;i<6;) { if(i==1) { zuhe(1,sum+1); i=2; } else if(i==2) { zuhe(2,sum+2); i=5; } else { zuhe(5,sum+5); i=6; } } } int main() { int sum=0; int min=1; zuhe(min,sum); printf("%d",num); }
相关文章推荐
- 利用自定义函数求四个数的最大公约数
- 面试题,小程序,在一个排序完毕的数组中,按顺序插入一个数
- cognos report同比环比以及默认为当前月分析
- 反向地址编码:拿到Location的经纬度,无须访问网络,直接可以得到定位到区的地址(androidApi提供)
- Reading CLR via c# 4th Edition
- R语言学习
- c++ 中关于int,unsigned int , short的关系与应用
- asp.net mvc4 运用 paypal sdk实现支付
- 曾经汇编常用指令整理笔记
- ADC 驱动实例开发
- 4.25 小结
- 父进程啊父进程
- 使用FindFirstFile,FindNextFile遍历一个文件夹
- OpenStack Nova-cell服务的源码解析(1)
- Android上的Mosquitto推送
- [Sciter系列] MFC下的Sciter–3.Sciter脚本与底层交互
- Eclipse C/C++开发环境搭建
- Ubuntu 10.04下安装Opengl glx
- 3.3 《硬啃设计模式》第12章 超级手机 - 外观模式(Facade Pattern)
- Nova Scheduler 调度过程简述