返回
理解动态规划,通关LeetCode入门题!
前端
2023-10-02 06:33:43
一、动态规划入门
动态规划是一种解决复杂问题的策略,它将一个复杂的问题分解成一系列较小的子问题,然后逐一求解这些子问题,并将子问题的解组合起来得到最终解。动态规划的思想是,如果一个问题可以分解成一系列子问题,并且每个子问题都可以独立地求解,那么就可以通过动态规划来求解这个复杂的问题。
动态规划的常见解题方法包括:
- 自顶向下法: 从问题的最优解出发,逐步分解成子问题,逐一求解子问题,最终得到问题的最优解。
- 自底向上法: 从问题的最基本子问题出发,逐层向上求解子问题,最终得到问题的最优解。
二、动态规划经典题目
动态规划有很多经典题目,例如:
- 斐波那契数列: 计算第 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]
总结
动态规划是一种强大的算法,可以用来解决许多复杂的问题。它通过将一个复杂的问题分解成一系列较小的子问题,然后逐一求解这些子问题,并将子问题的解组合起来得到最终解。动态规划的思想是,如果一个问题可以分解成一系列子问题,并且每个子问题都可以独立地求解,那么就可以通过动态规划来求解这个复杂的问题。