题解:AcWing 897 最长公共子序列
【题目来源】
AcWing:897. 最长公共子序列 - AcWing题库
【题目描述】
给定两个长度分别为 \(N\) 和 \(M\) 的字符串 \(A\) 和 \(B\),求既是 \(A\) 的子序列又是 \(B\) 的子序列的字符串长度最长是多少。
【输入】
第一行包含两个整数 \(N\) 和 \(M\)。
第二行包含一个长度为 \(N\) 的字符串,表示字符串 \(A\)。
第三行包含一个长度为 \(M\) 的字符串,表示字符串 \(B\)。
字符串均由小写字母构成。
【输出】
输出一个整数,表示最大长度。
【输入样例】
4 5
acbd
abedc
【输出样例】
3
【算法标签】
《AcWing 897 最长公共子序列》 #动态规划# #线性DP#
【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 1005; // 定义常量N,表示数组的最大长度
int n, m; // n和m分别表示两个字符串的长度
char a[N], b[N]; // a和b分别存储两个字符串
int f[N][N]; // f[i][j]表示a的前i个字符和b的前j个字符的最长公共子序列的长度
int main()
{
// 输入两个字符串的长度n和m,以及两个字符串a和b
// 注意:a和b的输入从下标1开始,即a+1和b+1
cin >> n >> m >> a+1 >> b+1;
// 动态规划求解最长公共子序列
for (int i = 1; i <= n; i++) // 遍历字符串a的每个字符
for (int j = 1; j <= m; j++) // 遍历字符串b的每个字符
{
// f[i][j]的值取f[i-1][j]和f[i][j-1]中的较大值
// 这表示当前字符a[i]或b[j]不参与构成最长公共子序列
f[i][j] = max(f[i-1][j], f[i][j-1]);
// 如果a[i]等于b[j],则可以考虑将a[i]和b[j]加入到最长公共子序列中
// 此时f[i][j]的值取f[i-1][j-1] + 1和当前f[i][j]中的较大值
if (a[i] == b[j])
f[i][j] = max(f[i][j], f[i-1][j-1] + 1);
}
// 输出a和b的最长公共子序列的长度
cout << f[n][m] << endl;
return 0;
}
【运行结果】
4 5
acbd
abedc
3
浙公网安备 33010602011771号