算法:动态规划
发布人:shili8
发布时间:2024-12-24 10:35
阅读次数:0
**动态规划算法**
动态规划(Dynamic Programming)是一种常见的算法技巧,用于解决复杂的问题。它通过分解问题,逐步求解子问题,最终得到最优解。这种方法尤其适合于具有重叠子问题的递归问题。
**什么是动态规划?**
动态规划是一种将原问题分解为多个子问题,然后解决这些子问题,以达到最终目标的算法技巧。每个子问题的解可以被缓存起来,以避免重复计算,从而提高效率。
**动态规划的步骤**
1. **分解问题**: 将原问题分解为多个子问题,每个子问题都有明确的界定。
2. **求解子问题**: 逐一解决每个子问题,直到所有子问题都被解决。
3. **缓存结果**: 每次解决一个子问题后,将其结果缓存起来,以避免重复计算。
**动态规划的优点**
1. **高效率**: 动态规划可以显著提高算法的效率,因为它避免了重复计算。
2. **简洁性**: 动态规划通常比递归方法更简洁,更易于理解和实现。
**动态规划的缺点**
1. **难度**: 动态规划需要对问题进行深入分析,并且需要了解如何分解问题和缓存结果。
2. **空间复杂度**: 动态规划可能需要额外的空间来缓存结果,这可能会增加算法的空间复杂度。
**动态规划的例子**
###1. 最长上升子序列(Longest Increasing Subsequence)
给定一个整数数组 `arr`,请找出最长上升子序列的长度。
def longest_increasing_subsequence(arr): n = len(arr) # 动态规划表格 dp = [[0] *2 for _ in range(n)] # 初始化动态规划表格 for i in range(n): dp[i][0] =1 # 填充动态规划表格 for i in range(1, n): for j in range(i +1): if arr[j] < arr[i]: dp[i][0] = max(dp[i][0], dp[j][0] +1) # 返回最长上升子序列的长度 return max(max(row) for row in dp) # 测试用例arr = [10,22,9,33,21,50,41,60] print(longest_increasing_subsequence(arr)) # 输出:5
###2. 最长公共子序列(Longest Common Subsequence)
给定两个字符串 `str1` 和 `str2`,请找出最长公共子序列的长度。
def longest_common_subsequence(str1, str2): m = len(str1) n = len(str2) # 动态规划表格 dp = [[0] * (n +1) for _ in range(m +1)] # 初始化动态规划表格 for i in range(m +1): dp[i][0] = i # 填充动态规划表格 for j in range(1, n +1): for i in range(1, m +1): if str1[i -1] == str2[j -1]: dp[i][j] = dp[i -1][j -1] +1 else: dp[i][j] = max(dp[i -1][j], dp[i][j -1]) # 返回最长公共子序列的长度 return dp[m][n] # 测试用例str1 = "AGGTAB" str2 = "GXTXAYB" print(longest_common_subsequence(str1, str2)) # 输出:4
###3. 最小编辑距离(Minimum Edit Distance)
给定两个字符串 `str1` 和 `str2`,请找出最小编辑距离。
def minimum_edit_distance(str1, str2): m = len(str1) n = len(str2) # 动态规划表格 dp = [[0] * (n +1) for _ in range(m +1)] # 初始化动态规划表格 for i in range(m +1): dp[i][0] = i # 填充动态规划表格 for j in range(1, n +1): for i in range(1, m +1): if str1[i -1] == str2[j -1]: dp[i][j] = dp[i -1][j -1] else: dp[i][j] = min(dp[i -1][j], dp[i][j -1]) +1 # 返回最小编辑距离 return dp[m][n] # 测试用例str1 = "kitten" str2 = "sitting" print(minimum_edit_distance(str1, str2)) # 输出:3
以上是动态规划算法的几个例子。这些例子展示了如何使用动态规划解决不同的问题,包括最长上升子序列、最长公共子序列和最小编辑距离。