返回

理解动态规划,通关LeetCode入门题!

前端

一、动态规划入门

动态规划是一种解决复杂问题的策略,它将一个复杂的问题分解成一系列较小的子问题,然后逐一求解这些子问题,并将子问题的解组合起来得到最终解。动态规划的思想是,如果一个问题可以分解成一系列子问题,并且每个子问题都可以独立地求解,那么就可以通过动态规划来求解这个复杂的问题。

动态规划的常见解题方法包括:

  • 自顶向下法: 从问题的最优解出发,逐步分解成子问题,逐一求解子问题,最终得到问题的最优解。
  • 自底向上法: 从问题的最基本子问题出发,逐层向上求解子问题,最终得到问题的最优解。

二、动态规划经典题目

动态规划有很多经典题目,例如:

  • 斐波那契数列: 计算第 n 个斐波那契数。
  • 最长公共子序列: 求两个字符串的最长公共子序列。
  • 最长公共子串: 求两个字符串的最长公共子串。
  • 背包问题: 在一个背包容量有限的情况下,从一堆物品中选择一些物品放入背包,使得背包的总价值最大。
  • 最短路径问题: 在一个图中,从一个顶点到另一个顶点的最短路径。

三、动态规划入门题

现在,让我们通过一个 LeetCode入门题来学习动态规划。

题目:

按摩师每天最多可以按摩一位客人。每次按摩的收益为[Ai]元。不同天获得的收益是独立的。

请找出连续 n 天中的最大收益。

示例:

输入:[1, 2, 3, 1]
输出:4
解释:第一天,按摩师没有预约,第二天,按摩师接了预约,获得了2元收益,第三天,按摩师接了预约,获得了3元收益,第四天,按摩师没有预约。因此,按摩师的最大收益为4元。

解题思路:

这道题可以使用动态规划来求解。我们定义状态dp[i]为按摩师在第i天结束时所能获得的最大收益。那么,状态dp[i]可以由以下两个子状态得到:

  • dp[i] = dp[i-1],即按摩师在第i天不接预约,那么他的收益就是前一天的最大收益。
  • dp[i] = dp[i-2] + Ai,即按摩师在第i天接预约,那么他的收益就是前一天的最大收益加上今天的收益。

我们只需要使用动态规划的自底向上法,从第1天开始,逐天计算出dp[i]的值,最后得到dp[n]的值,即按摩师在第n天结束时所能获得的最大收益。

代码实现:

def maxProfit(A):
  dp = [0] * len(A)
  dp[0] = A[0]
  dp[1] = max(A[0], A[1])
  for i in range(2, len(A)):
    dp[i] = max(dp[i-1], dp[i-2] + A[i])
  return dp[-1]

总结

动态规划是一种强大的算法,可以用来解决许多复杂的问题。它通过将一个复杂的问题分解成一系列较小的子问题,然后逐一求解这些子问题,并将子问题的解组合起来得到最终解。动态规划的思想是,如果一个问题可以分解成一系列子问题,并且每个子问题都可以独立地求解,那么就可以通过动态规划来求解这个复杂的问题。