AcWing 897. 最长公共子序列
动态规划就是多见识应用题就完事儿了,也没有什么好说的。
讲解参考:
【E05 线性DP 最长公共子序列】
#include<iostream>
#include<algorithm>
#define N 1010
using namespace std;
char a[N],b[N];
int n,m;
int f[N][N];
int main(){
cin >> n >> m >> a + 1 >> b + 1 ;
for(int i = 1; i <= n ; ++ i) {
for(int j = 1; j <= m ; ++ j){
if(a[i] == b[j]){
f[i][j] = f[i - 1][j - 1] + 1;
}else{
f[i][j] = max(f[i - 1][j],f[i][j - 1]);
}
}
}
cout << f[n][m];
return 0;
}
输出最长公共子序列的代码,(STL版)
Runtime环境:c++17
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // 用于 reverse 函数
using namespace std;
pair<int, string> lcs(const string& s1, const string& s2) {
int m = s1.size();
int n = s2.size();
// 初始化 dp 数组
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
// 填充 dp 数组
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
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]);
}
}
}
// 获取 LCS 的长度
int lcs_length = dp[m][n];
// 回溯找到 LCS 序列
string lcs_seq;
int i = m, j = n;
while (i > 0 && j > 0) {
if (s1[i - 1] == s2[j - 1]) {
lcs_seq.push_back(s1[i - 1]);
--i;
--j;
} else if (dp[i - 1][j] > dp[i][j - 1]) {
--i;
} else {
--j;
}
}
// 由于回溯是从最后开始的,所以需要反转字符串
reverse(lcs_seq.begin(), lcs_seq.end());
return {lcs_length, lcs_seq};
}
int main() {
string s1 = "ABCBDABQ";
string s2 = "BDCABQ";
// 调用 LCS 函数
auto [length, sequence] = lcs(s1, s2);
// 输出结果
cout << "最长公共子序列长度: " << length << endl;
cout << "最长公共子序列: " << sequence << endl;
return 0;
}
c版
#include<iostream>
#include<algorithm>
#define N 11
using namespace std;
char a[N],b[N];
int n,m;
int f[N][N];
char seq[N];
int main(){
cin >> n >> m >> a + 1 >> b + 1 ;
for(int i = 1; i <= n ; ++ i) {
for(int j = 1; j <= m ; ++ j){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(a[i]==b[j]) f[i][j]=max(f[i][j],f[i-1][j-1]+1);
}
}
cout << f[n][m] << endl;
//最长子序列输出
int i = n , j = m;
string str;
while(i&&j){
if(a[i] == b[j]){
str += a[i];
i--,j--;
}else if(f[i - 1][j] > f[i][j - 1]){
i--;
}else{
j--;
}
}//不逆置字符串,直接逆序输出就完事儿了
for(int i=str.size()-1;i>=0;--i)
cout << str[i];
return 0;
}
PS,输出最长子序列的代码我尝试了10位的两个,好像是正确的,输出长度的啃腚没问题,输出最长子序列是啥的没咋仔细验证过,是GPT生成的代码