采用动态规划法,求序列S1=“AGGTAB”和S2=“GXTXAYB”的最长公共子序列。要求列出状态转移函数以及动态规划数组dp。分析具体每一步
时间: 2024-05-25 20:14:18 浏览: 4
状态转移函数:
设dp[i][j]为S1的前i个字符与S2的前j个字符的最长公共子序列长度。则当S1[i]==S2[j]时,dp[i][j] = dp[i-1][j-1] + 1;否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
动态规划数组dp:
G X T X A Y B
A 0 0 0 0 1 1 1
G 1 0 0 1 1 1 1
G 1 0 0 1 1 1 1
T 1 1 1 1 1 1 1
A 1 1 1 1 2 2 2
B 1 1 1 1 2 2 3
分析具体每一步:
1. 当i=0或j=0时,dp[i][j]=0;
2. 当S1[i]==S2[j]时,dp[i][j] = dp[i-1][j-1] + 1,此时S1[i]和S2[j]都在最长公共子序列中,将它们加入最长公共子序列中;
3. 当S1[i]!=S2[j]时,dp[i][j] = max(dp[i-1][j], dp[i][j-1]),此时S1[i]和S2[j]中至少有一个不在最长公共子序列中,因此需要比较dp[i-1][j]和dp[i][j-1]来决定最长公共子序列的长度;
4. 最终dp[n][m]即为S1和S2的最长公共子序列长度。反向追踪dp数组可以得到所有的最长公共子序列。
相关问题
动态规划法求最长公共子序列,要求自己输入元素
好的,下面我将介绍使用动态规划法求解最长公共子序列问题。
首先,让我们了解一下什么是最长公共子序列。最长公共子序列(LCS)是指两个或多个字符串中,所有顺序相同且长度最长的子序列。
接下来,我们按照以下步骤使用动态规划求解LCS问题:
1. 定义状态:设字符串A和B的长度分别为m和n,则定义一个m+1行、n+1列的二维数组dp,其中dp[i][j]表示A的前i个字符和B的前j个字符的LCS长度。
2. 初始化:将dp数组第一行和第一列的元素全部置为0,因为任意一个字符串与空字符串的LCS长度均为0。
3. 状态转移方程:当A[i]等于B[j]时,dp[i][j] = dp[i-1][j-1] + 1;否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
4. 最优解:dp[m][n]即为A和B的LCS长度。
5. 逆推求解LCS:从dp[m][n]开始,根据状态转移方程逆推得到LCS。
下面是Python代码实现:
```python
def lcs(A, B):
m, n = len(A), len(B)
dp = [[0] * (n+1) for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if A[i-1] == B[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
length = dp[m][n]
result = []
i, j = m, n
while i > 0 and j > 0:
if A[i-1] == B[j-1]:
result.append(A[i-1])
i -= 1
j -= 1
elif dp[i-1][j] > dp[i][j-1]:
i -= 1
else:
j -= 1
result.reverse()
return length, ''.join(result)
```
其中,A和B分别为输入的字符串,返回值为LCS长度和LCS本身。
动态规划法求最长公共子序列c++代码,要求自己输入元素
以下是使用动态规划求解最长公共子序列的C++代码:
```c++
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1005;
int dp[MAXN][MAXN];
int main() {
int n, m;
cin >> n >> m;
int a[MAXN], b[MAXN];
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= m; i++) {
cin >> b[i];
}
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i] == b[j]) {
dp[i][j] = dp[i-1][j-1] + 1;
} else {
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
}
cout << dp[n][m] << endl;
return 0;
}
```
这里使用了一个二维数组`dp`来保存最长公共子序列的长度,其中`dp[i][j]`表示第一个序列前i个元素与第二个序列前j个元素的最长公共子序列长度。然后通过两个for循环遍历两个序列的每个元素,如果相等则更新`dp[i][j]`,否则取`dp[i-1][j]`与`dp[i][j-1]`的较大值。最后输出`dp[n][m]`即可。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)