题解: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
posted @ 2026-02-25 08:02  团爸讲算法  阅读(0)  评论(0)    收藏  举报