最长公共子序列,这是 B站 一个博主的讲解视频,讲的很好,看完这个视频你接下来甚至可以不看我这篇博客,但如果你觉得视频太长,欢迎继续往下看看我从视频里提取的精华内容。
目录
1、定义
最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题。一个数列 ,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则称为已知序列的最长公共子序列。
上面的解释是百度给出的,我再用白话解释一下,其实也就是给出几个不同的字符串(一般是两个),然后求它们的公共子序列,可以不连续。举个例子,字符串algorithms和alchemist(为了方便观察,LCS我用红色加粗表示)的LCS即alhms。
2、常规题目
描述:
给定两个序列s1、s2,求二则的公共子序列长度。
输入:
第一行输入第一个序列
第二行输入第二个序列
输出:
输出一个数字,即两个序列的公共子序列长度。
3、解题思路
主要还是用到动态规划,但要理清楚其中的意思。
① 设计状态
设 f[i][j] 是序列 si={x1,x2,...,xi} 和序列 sj={y1,y2,...,yj} 的公共子序列长度。
② 状态转移方程
现在 i、j 对应三种不同的方程
f[i][j] = 0 --> i=0或者j=0,si和sj中任意一个序列长度为零,那么它们的 LCS长度就只能为零
f[i][j] = f[i-1][j-1] + 1 --> xi=yj,两个序列的最后一各字符相等,说明长度至少要加一,加一后直接剪掉这个字符,再继续对照 i-1 和 j-1对应的字符,依次对照
f[i][j] =max(f[i-1][j],f[i][j-1])--> xi!=yj,这个用例子说明,假设求abcd和acde的LCS长度,字符 d!=e,现在有两种选择,要么求 abcd 和 acd 的LCS,要么求 abc和 acde 的LCS,但既然是求最长LCS,那么选择两种方案的最大值即可。
4、解题代码
// 求最长公共子序列 -- dp
#include <bits/stdc++.h>
using namespace std;
char s1[100],s2[100];
int f[100][100];
int main()
{
int n,m,i,j;
gets(s1);
gets(s2);
n=strlen(s1),m=strlen(s2);
// 状态转移方程一 --> f[100][100]本来全都为零,不用管
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(s1[i-1]==s2[j-1]) 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;
}
/*案例
algorithms
alchemist
结果: 5
*/
5、扩展
上面代码求出的只是LCS的长度,现在我们尝试直接求出这个序列,而不是长度。
// 求最长公共子序列 -- dp
#include <bits/stdc++.h>
using namespace std;
char s1[100],s2[100];
int f[100][100];
void LCS(int i,int j)
{
if(i==0||j==0) return ; //回溯
if(s1[i-1]==s2[j-1])
{
LCS(i-1,j-1); //递归
cout<<s1[i-1];
}
else if(f[i-1][j]>f[i][j-1])
{
LCS(i-1,j);
}
else
{
LCS(i,j-1);
}
}
int main()
{
int n,m,i,j;
gets(s1);
gets(s2);
n=strlen(s1),m=strlen(s2);
// 状态转移方程一 --> f[100][100]本来全都为零,不用管
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(s1[i-1]==s2[j-1]) 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]<<endl; // 序列长度
LCS(n,m); // 求序列 函数
return 0;
}
/*案例
algorithms
alchemist
结果:
5
alhms
*/
结果:

本文介绍了最长公共子序列(LCS)的概念,通过一个B站博主的视频讲解,详细阐述了如何使用动态规划求解LCS。文章提供了解题思路,包括状态设计和状态转移方程,并给出了两段C++代码,分别用于计算两个字符串的LCS长度和输出LCS序列。以字符串'algorithm'和'alchemist'为例,展示了LCS为'alhms',长度为5。
1012

被折叠的 条评论
为什么被折叠?



