动态规划策略实现最长公共子序列。 最长公共子序列问题:对两个类型相同的序列(输入),用动态规划方法计算他们的最长公共子序列,并输出最长公共子序列的长度值。
时间: 2023-08-13 13:31:46 浏览: 48
好的,最长公共子序列问题可以用动态规划策略来解决。下面是动态规划策略的实现步骤:
1.定义状态:设dp[i][j]为序列1的前i个元素和序列2的前j个元素的最长公共子序列长度。
2.状态转移方程:如果序列1的第i个元素与序列2的第j个元素相同,则dp[i][j] = dp[i-1][j-1] + 1;否则dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
3.初始化:dp[0][j] = 0, dp[i][0] = 0。
4.输出结果:dp[m][n]即为两个序列的最长公共子序列长度。
下面是Python代码实现:
```python
def longest_common_subsequence(str1, str2):
m, n = len(str1), len(str2)
dp = [[0] * (n+1) for _ in range(m+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]
```
调用该函数,可以得到两个序列的最长公共子序列长度。
相关问题
Python动态规划策略实现最长公共子序列。最长公共子序列问题:对两个类型相同的序列(输入),用动态规划方法计算他们的最长公共子序列,并输出最长公共子序列和最长公共子序列的长度值。
好的,这是一个经典的动态规划问题。我们可以使用一个二维数组dp[i][j]表示序列1的前i个字符和序列2的前j个字符的最长公共子序列的长度。具体实现步骤如下:
1. 初始化dp数组,dp[0][j]和dp[i][0]均为0,表示空序列的最长公共子序列长度为0。
2. 遍历序列1和序列2,如果当前字符相等,则dp[i][j] = dp[i-1][j-1]+1;否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1]),即选择序列1前i-1个字符和序列2前j个字符的最长公共子序列长度,或者选择序列1前i个字符和序列2前j-1个字符的最长公共子序列长度。
3. 最后,根据dp数组反向回溯,找到最长公共子序列。
下面是Python代码实现:
```python
def lcs(s1, s2):
m, n = len(s1), len(s2)
dp = [[0] * (n+1) for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if s1[i-1] == s2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
res = ""
i, j = m, n
while i > 0 and j > 0:
if s1[i-1] == s2[j-1]:
res = s1[i-1] + res
i -= 1
j -= 1
elif dp[i-1][j] > dp[i][j-1]:
i -= 1
else:
j -= 1
return res, dp[m][n]
```
这个函数接受两个字符串作为参数s1和s2,返回它们的最长公共子序列和最长公共子序列的长度值。
动态规划策略实现最长公共子序列python
最长公共子序列问题是一种经典的动态规划问题,在此为您提供 Python 代码实现:
```python
def lcs(str1, str2):
m = len(str1)
n = len(str2)
# 创建一个 m+1 行,n+1列的二维数组,用于保存子问题的最优解
dp = [[0] * (n+1) for _ in range(m+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], get_lcs(dp, str1, str2)
def get_lcs(dp, str1, str2):
i, j = len(str1), len(str2)
lcs_str = ''
while i > 0 and j > 0:
if str1[i-1] == str2[j-1]:
lcs_str = str1[i-1] + lcs_str
i -= 1
j -= 1
elif dp[i-1][j] >= dp[i][j-1]:
i -= 1
else:
j -= 1
return lcs_str
```
这个代码中,我们首先创建一个二维数组 dp 来保存子问题的最优解。然后,我们使用两个嵌套的循环遍历 str1 和 str2 中的每个字符,并计算子问题的最优解。最后,我们返回最长公共子序列的长度以及最长公共子序列本身。
在计算子问题的最优解时,我们会根据当前字符是否相等来进行判断。如果相等,那么最长公共子序列的长度应该加上 1,同时我们需要继续考虑 str1 和 str2 中下一个字符的匹配。如果不相等,我们就需要在 str1 和 str2 中分别跳过一个字符,然后继续考虑下一个字符的匹配。
最后,我们使用一个 while 循环来重建最长公共子序列。我们从 dp[m][n] 开始,一步步往回找到最长公共子序列的每个字符,并将它们添加到 lcs_str 中。
阅读全文