斐波那契数列
斐波那契数列是这样的一个数列:1, 1, 2, 3, 5, 8, 13, 21, ...,这个数列从第3个数开始,每个数都等于前面两个数的和。这个数列与大自然中植物的关系极为密切,几乎所有花朵的花瓣都来自这个数列中的一项数字,同时在植物的叶、枝、茎等排列中也存在斐波那契数列。
问题:完成程序,输出斐波那契数列中的第10项
图解思路,自下而上:
程序实现,自下而上:
#includeusing namespace std;int f(int n){ int a1=1,a2=1,a3; for(int i=3;i<=n;i++){ a3=a2+a1;//自下而上,依次计算两项和 a1=a2;//上次的a2存放到新的次数a1中,实现a1向右移动 a2=a3;//上次的a3存放到新的次数a2中,实现a2向右移动 } return a3;//返回最后索引项}int main(){ cout<10)<< return 0;}
图解思路,自上而下:
程序实现,自上而下:
#includeusing namespace std;int a(int n){ if(n==1||n==2){ return 1;//1、初始条件(边界条件),最底层 }else{ return a(n-1)+a(n-2);//2、关系式,化整为零把大问题化为多个子问题 }}int main(){ cout<10)<< return 0;}
自上而下的核心思想是,想要解决第n项问题,必须解决第n-1项问题,想要解决第n-1项问题,必须解决第n-2项问题,依次向下递推直到遇到最初始条件,再根据项与项之间关系式可以向上求解得出答案!
递归:程序调用自身的编程技巧称为递归
递归特点:通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
问题:完成程序,输出n的阶乘
阶乘:一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。
公式:n!=1×2×3×...×(n-1)×n
程序实现,递归(自上而下):
#include#includeusing namespace std;long long a(int n){ if(n==0){ return 1; }else{ return n*a(n-1);//想要知道第n项,必须解决第n-1项,依次向前推进 }}int main(){ printf("%d",a(5)) return 0;}
汉诺塔(Hanoi)
有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序防止n个盘。实现把A杆上的盘全部移到C杆上,并保持原有顺序叠好。
规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
两个圆盘图解思路:
第一步图解:
第二步图解:
第三步图解:
n个圆盘图解思路:
第一步图解:
把n-1个圆盘移动到目标杆,从上向下看就是一大步,不用纠结为什么可以一次移动这么多,这里这是运用了从上向下的递归思想,递归的核心思想是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解!
第二步图解:向前推进一步就能实现最后一个盘子移动到目标杆,依次推进直到把n-1个盘子依次移动到目标杆!
第三步图解:
调换原始杆、中介杆以及目标杆的位置(程序中调换的实际是变量中的值),和第一步一样重新递归!
程序实现:
#includeusing namespace std;void hanoi(char A,char B,char C,int n){ if(n>0){//圆盘的个数必须大于0 hanoi(A,C,B,n-1);//第一步:将前n-1项从A移动到B,A--->B cout<"从 "< hanoi(B,A,C,n-1);//第三步:将第n-1项从B移动到C,B--->C }}int main(){ hanoi('A','B','C',10); return 0;}