递归和动态规划

本文探讨了递归和动态规划的概念,强调了两者的关系。递归是通过直接或间接调用自身解决问题,而动态规划则通过查表优化递归避免重复计算。文章通过实例解释了递归的三个要素,并对比了递归和动态规划在解决问题时的效率差异,指出动态规划利用状态转移方程和临界条件降低复杂度。最后,列举了相关动态规划问题供进一步学习。
摘要由CSDN通过智能技术生成

动态规划可以理解为是查表的递归。那么什么是递归?

递归

定义:递归算法是一种直接或者间接调用自身函数或者方法的算法。

算法中使用递归可以很简单地完成一些用循环实现的功能,比如二叉树的左中右序遍历。递归在算法中有非常广泛的使用, 包括现在日趋流行的函数式编程。

纯粹的函数式编程中没有循环,只有递归。

接下来我们来讲解一下递归。通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解

递归的三个要素

  1. 一个问题的解可以分解为几个子问题的解

  2. 子问题的求解思路除了规模之外,没有任何区别

  3. 有递归终止条件

我这里列举了几道算法题目,这几道算法题目都可以用递归轻松写出来:

  • 递归实现 sum

  • 二叉树的遍历

  • 走楼梯问题

  • 汉诺塔问题

动态规划

如果说递归是从问题的结果倒推,直到问题的规模缩小到寻常。那么动态规划就是从寻常入手, 逐步扩大规模到最优子结构。 这句话需要一定的时间来消化, 如果不理解,可以过一段时间再来看。

递归的解决问题非常符合人的直觉,代码写起来比较简单。但是我们通过分析(可以尝试画一个递归树),可以看出递归在缩小问题规模的同时可能会 重复计算。279.perfect-squares[1] 中 我通过递归的方式来解决这个问题,同时内部维护了一个缓存 来存储计算过的运算,那么我们可以减少很多运算。这其实和动态规划有着异曲同工的地方。

我们结合求和问题来讲解一下, 题目是给定一个数组,求出数组中所有项的和,要求使用递归实现。

代码:

function sum(nums) {
  if (nums.length === 0) return 0;
  if (nums.length 
好的,下面我将分别给出递归动态规划的解法,并使用 Python 代码来实现。 01背包问题是一个经典的动态规划问题,其表述如下:有一个背包,容量为C,有n个物品,每个物品有重量w和价值v,现在要把这些物品放入背包中,使得背包中物品的总价值最大,求最大价值。 1. 递归解法 递归解法比较简单,但是由于存在大量的重复计算,效率比较低。具体思路是:对于每个物品,有两种选择,放入背包或不放入背包,然后递归处理剩下的物品。 代码如下: ```python def knapsack01_recursion(C, w, v, n): if n == 0 or C == 0: return 0 if w[n-1] > C: return knapsack01_recursion(C, w, v, n-1) else: return max(v[n-1] + knapsack01_recursion(C-w[n-1], w, v, n-1), knapsack01_recursion(C, w, v, n-1)) ``` 2. 动态规划解法 动态规划解法使用一个二维数组来存储中间状态,具体思路是:定义一个二维数组dp[i][j],表示前i个物品放入容量为j的背包中可以获得的最大价值。对于每个物品,有两种选择,放入背包或不放入背包,状态转移方程为: dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i-1]]+v[i-1]),其中w[i-1]和v[i-1]分别表示第i个物品的重量和价值。 最终的结果为dp[n][C]。 代码如下: ```python def knapsack01_dp(C, w, v, n): dp = [[0 for _ in range(C+1)] for _ in range(n+1)] for i in range(1, n+1): for j in range(1, C+1): if w[i-1] > j: dp[i][j] = dp[i-1][j] else: dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i-1]]+v[i-1]) return dp[n][C] ``` 以上就是使用递归动态规划解决01背包问题的Python代码实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值