基本算法-02递推与递归 学习笔记

一、理论与概述

宏观描述:对于一个待求解的问题,当它局限在某边界、某个小范围或者某种特殊情形下时,其答案往往时已知的。如果能够将该解答的应用场景扩大到原问题的状态空间,并且扩展过程的每个步骤具有相似性,就可以考虑使用递推和递归求解。

  • 以已知的“问题边界”为起点向“原问题”正向推导的扩展方式就是递推
  • 当推导的路线难以确定,这时以“原问题”为起点尝试寻找把状态空间缩小到已知的“问题边界”的路线,再通过该路线反向回溯的遍历方式就是递归

使用递推、递归要求“原问题”与“问题边界”之间的每个变换步骤具有相似性,这样我们才能够设计一段程序实现这个步骤,将其重复作用与间隔之中。即:程序在每个步骤上应该面对同种种类的问题,这些问题都是原问题的一个子问题,可能仅在规模或者某些限制上有所区别,并且能够使用“求解原问题的程序”进行求解。

对于递归算法,有以上前提后,我们就可以让程序在每个变换过程中执行以下三个操作:

  1. 缩小问题状态空间的规模。这意味着程序尝试寻找在“原问题”和“问题边界”之间的变换路线,并向正在探索的路线上迈出一步。
  2. 尝试求解规模缩小以后的问题,结果可能是成功或是失败的。
  3. 如果成功,即找到了规模缩小以后的问题的答案,那么将答案扩展到当前问题,如果失败,那么重新回到当前问题,程序可能会继续寻找当前问题的其他变换路线,直至最终确定当前问题无法求解。

关键的两点:

  • “如何尝试求解规模缩小的问题”:因为规模缩小后的问题是原问题的一个子问题。所以我们可以把它视为一个新的“原问题”有相同的程序进行求解。这就是所谓的“自身调用自身”
  • 如果求解子问题失败,程序需要重新回到当前问题去寻找其他的变换路线,因此把当前问题缩小为子问题时所作的对当前问题状态产生影响的事应该全部失效,这是所谓的“回溯时还原现场

递归的基本单元是由”缩小“、”求解“、”扩展“组成的一种变换步骤。

二、递推与递归的简单应用

常见的枚举形式和遍历方式

枚举形式 状态空间规模 一般遍历方式
多项式 n^k, k为常数 循环(for)、递归
指数 k^n,k为常数 递归、位运算
排列 n! 递归、C++ next_permutation
组合 Cn(m) 递归+剪枝

分治

分治法把一个问题划分为若干个规模更小的子问题,对这些子问题递归求解,然后在回溯时通过他们推导出原问题的解

分形

留坑…

猜你喜欢

转载自blog.csdn.net/yanweiqi1754989931/article/details/110789046