递归:
- 将问题分解成相似的子问题
- 递归函数:内存中开辟了大量函数栈
- 汉诺塔:
化简:将n个从a移动到c写成:Hanoi(n,a,b,c)
- 将n-1个从a移动到b:Hanoi(n-1,a,c,b)//子问题
- 将第n个移动到c
- 将n-1个从b移动到c:Hanoi(n-1,b,a,c)//子问题
其中第13步都与原问题相似,可以通过递归实现
- N皇后:
分析:8皇后能用8重循环接,N皇后?递归来实现多重循环
N重循环:当k==N时(实际有N个已经摆好),控制了循环重数。
化简:从第一行逐行摆放第i个皇后记为Queue(i)
判断:第i个皇后有N个位置可以放,当选中位置k后(for循环),要与前i-1个的位置判断不能在同一列或者对角线上
递归:当位置i满足条件的情况下,执行Queue(i+1),此时前i个都已经摆好
多重循环:当某次不满足条件时会返回到上一层的for来改变假设位置,会遍历到所有情况
tips:对角判断:两个位置行相减的绝对值与列相减得绝对值相等 逆波兰表达式:
分析:题目的定义就是递归的
exp():读入一个逆波兰并求值
实现:cin.peek()看第一个字符后确定是边界还是递归。表达式求值:
分析:递归定义的问题
表达式:项+-,项:因子*/,因子:(表达式)或者数字`
exp():读入表达式并返回其值
term():读入一项并求值
factor():读入一个因子并返回值。台阶问题:分解成子问题
分析:第一步走1级,第二步走2级。斐波那契数列。
化简:f(n):走n级的方法数。f(n)=f(n-1)+f(n-2)- 放苹果:分解
分析:f(i,m):将i个苹果放到m个盆里的方法,i < m时总会有盘子是空的至多用到i个盘子:f(i,i)
- 有空盘子:摆法等于让一个盘子为空,f(i,m)=f(i,m-1).`
- 没空盘子:先将每个盘子放一个苹果后的剩余苹果的摆法:f(i,m)=f(i-m,m);
边界条件:i=0时f=1(没苹果);m=0时f=0(没盘子).
递归程序:f(i,m)=f(i-m,m)+f(i,m-1)
- 算24:以一个数组来算出24
分析:bool count24(int a[],int num):以数组a的num个数字能否算出24点。先任意取两个数字,做算术运算后和没使用的数字置于新数组b,调用count24(b,num-1)返回结果(当返回true时可以立即返回,只有所有都false时才返回false)。注意:减法和除法是因为先后顺序不同有2中结果,并且除法要判断分母不能为0.
总结:
- 多重循环:受参数n控制的递归调用。
- 递归定义:用递归实现递归定义。
- 子问题:分解成相似子问题。递归是算法中最重要也是最基本的,它是一种分解问题成子问题的思想,之后的分治和动规解题一般都是先按照递归理出思路在转换成动规来优化。`