当前位置:实例文章 » 其他实例» [文章]Acwing.897 最长公共子序列(动态规划)

Acwing.897 最长公共子序列(动态规划)

发布人:shili8 发布时间:2025-02-27 03:27 阅读次数:0

**最长公共子序列(Longest Common Subsequence,LCS)**

在计算机科学中,最长公共子序列问题是指给定两个序列(如字符串或数组),找出其中一个序列的最长连续子序列,它也是另一个序列的一个子序列。这个问题经常被用来解决生物信息学中的序列比对问题。

**动态规划法**

动态规划法是解决最长公共子序列问题的一种有效方法。基本思想是:对于两个序列的每个位置,计算出它们的最长公共子序列的长度,并将其存储在一个二维数组中,以便后续使用。

**算法步骤**

1. **初始化**:创建一个二维数组 `dp`,大小为 `(m+1)×(n+1)`,其中 `m` 和 `n` 是两个序列的长度。将所有元素初始化为 `0`。
2. **填充第一行和第一列**:对于每个位置 `i`(从 `0` 到 `m`)和 `j`(从 `0` 到 `n`),如果 `i==0` 或 `j==0`,则将 `dp[i][j]` 初始化为 `0`。否则,如果两个序列的当前字符相同,则 `dp[i][j]=dp[i-1][j-1]+1`。
3. **填充剩余元素**:对于每个位置 `i`(从 `1` 到 `m`)和 `j`(从 `1` 到 `n`),如果两个序列的当前字符相同,则 `dp[i][j]=dp[i-1][j-1]+1`。否则,取 `dp[i-1][j]` 和 `dp[i][j-1]` 的最大值,并将其赋给 `dp[i][j]`。
4. **读取结果**:最长公共子序列的长度存储在 `dp[m][n]` 中。

**示例代码**

def lcs(str1, str2):
 m = len(str1)
 n = len(str2)

 # 初始化二维数组 dp = [[0 for _ in range(n +1)] for _ in range(m +1)]

 # 填充第一行和第一列 for i in range(m +1):
 for j in range(n +1):
 if i ==0 or j ==0:
 dp[i][j] =0 elif str1[i -1] == str2[j -1]:
 dp[i][j] = dp[i -1][j -1] +1 # 填充剩余元素 for i in range(1, m +1):
 for j in range(1, n +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("最长公共子序列的长度:", lcs(str1, str2))


**注释**

* `dp` 是一个二维数组,用于存储两个序列的最长公共子序列的长度。
* `m` 和 `n` 是两个序列的长度。
* `i` 和 `j` 是 `dp` 的行和列索引。
* `str1[i -1] == str2[j -1]` 表示当前字符是否相同。
* `max(dp[i -1][j], dp[i][j -1])` 返回两个序列的最长公共子序列的长度。

**总结**

本文介绍了动态规划法解决最长公共子序列问题的方法。通过使用一个二维数组 `dp`,我们可以有效地计算出两个序列的最长公共子序列的长度。示例代码展示了如何实现这个算法,并提供了测试用例来验证其正确性。

相关标签:算法动态规划
其他信息

其他资源

Top