最长公共子序列
时间限制:3000 ms | 内存限制:65535 KB
难度:3
tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
接下来每组数据两行,分别为待测的两组字符串。每个字符串长度不大于1000.
2 asdf adfsd 123abc abc123abc
3 6
思路:
如图所示为最长公共子序列。(子序列是不连续的,子串是连续的)
现有两个序列X={x1,x2,x3,...xi},Y={y1,y2,y3,....,yi},
设有C[i,j]: 保存Xi与Yj的最长公共子序列(LFS)的长度。
演示过程如图所示,如果Xi,Yi相同,则取对角线的数+1;
如果Xi,Yi不相同,则对比上面或左边的数,取最大值+1;
根据下面的演示其实可以发现C[i,j]一直保存着当前(Xi,Yi)的最大子序列长度。
(1) 当X[i]=Y[j]时, C(i, j)=C(i-1, j-1) 1 。证明很简单。
(2) 当X[i]!=Y[j]时, 说明此事X[0...i]和Y[0...j]的最长公共子序列中绝对不可能同时含有X[i]和Y[j]。那么公共子序列可能以X[i]结尾,可能以Y[j]结尾,可以末尾都不含有X[i]或Y[j]。
因此 C(i, j)= MAX{Ci-1 , j), C(i, j-1)}
Explain in detail:
事实上,最长公共子序列问题也有最优子结构性质。
记:
Xi = <x1,x2,x3,....xi> 即X序列的前i个字符(1<= i <= m)(前缀)
Yj = <y1,y2,y3,....yi> 即Y序列的前j个字符(1<= j <= m)(前缀)
假定Z = <z1,z2,z3,...zk>是LCS(X,Y)中的一个。
·若xm = yn(最后一个字符相同),则不难用反正法证明:该字符必是X与Y的任一最长公共子序列Z(设长度为k)的最后一个字符,即有zk = xm = yn,且显然有Zk-1∈LCS(Xm-1,Yn-1),即Z的前缀Zk-1是Xm-1与Yn-1的最长公共子序列。此时,问题化归成求Xm-1与Yn-1的LCS(LCS(X,Y))的长度等于LCS(Xm-1,Yn-1)的长度加1)。
·若xm≠yn,则亦不难用反证法证明:要么Z∈LCS(Xm-1, Y),要么Z∈LCS(X , Yn-1)。由于zk≠xm与zk≠yn其中至少有一个必成立,若zk≠xm则有Z∈LCS(Xm-1 , Y);类似的,若zk≠yn 则有Z∈LCS(X , Yn-1)。此时,问题化归成求Xm-1与Y的LCS及X与Yn-1的LCS。LCS(X , Y)的长度为:max{LCS(Xm-1 , Y)的长度, LCS(X , Yn-1)的长度}。
由于上述当xm≠yn的情况中,求LCS(Xm-1 , Y)的长度与LCS(X , Yn-1)的长度,这两个问题不是相互独立的:两者都需要求LCS(Xm-1,Yn-1)的长度。另外两个序列的LCS中包含了两个序列的前缀的LCS,故问题具有最优子结构性质考虑用动态规划法。
Wrong:
#include<stdio.h> #include<string.h> int main() { int N,i,j; int alen,blen; char a[1005]; char b[1005]; char same[1005][1005]; //手抽这里写错了 应该是int类型…… scanf("%d",&N); while(N--) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(same,0,sizeof(same)); scanf("%s",a); scanf("%s",b); alen=strlen(a); blen=strlen(b); for(i=1;i<=alen;i++) for(j=1;j<=blen;j++) { if(a[i-1]==b[j-1]) same[i][j]=same[i-1][j-1]+1; //这里的字符要-1 else same[i][j]=(same[i-1][j]>same[i][j-1]?same[i-1][j]:same[i][j-1]); } printf("%d\n",same[alen][blen]); } return 0; }
AC:
#include<stdio.h> #include<string.h> int main() { int N,i,j; int alen,blen; char a[1005]; char b[1005]; int same[1005][1005]; scanf("%d",&N); while(N--) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(same,0,sizeof(same)); scanf("%s",a); scanf("%s",b); alen=strlen(a); blen=strlen(b); for(i=1;i<=alen;i++) for(j=1;j<=blen;j++) { if(a[i-1]==b[j-1]) same[i][j]=same[i-1][j-1]+1; else same[i][j]=(same[i-1][j]>same[i][j-1]?same[i-1][j]:same[i][j-1]); } printf("%d\n",same[alen][blen]); } return 0; }
总结:
吸收一下别人的解法。要静下心来慢慢理解。
相关推荐
动态规划中的最长公共子序列 动态规划中的最长公共子序列是指给定两个序列 X 和 Y,找到他们的最长公共子序列的长度和该子序列本身。该问题是计算机科学中的一类典型问题,广泛应用于数据压缩、数据挖掘、生物信息...
### 最长公共子序列动态规划算法 在计算机科学领域中,**最长公共子序列问题**(Longest Common Subsequence Problem, LCS)是一个经典的算法问题,它主要应用于文本比较、生物信息学中的DNA序列比对等领域。该问题...
【最长公共子序列(动态规划)】是一种经典的算法问题,主要应用于序列比对、文本处理等领域。本实验报告详尽地介绍了如何运用动态规划解决这一问题。 动态规划是一种解决复杂问题的有效方法,它通过将大问题分解为...
算法设计-最长公共子序列动态规划算法 动态规划算法是解决最长公共子序列问题的有效方法。该算法通过建立一个二维数组来存储子问题的解,从而避免了重复计算。 知识点一:最长公共子序列问题 最长公共子序列问题...
总之,最长公共子序列问题可以通过动态规划有效地解决,通过构建并填充c和b数组,不仅可以得到LCS的长度,还可以重建LCS本身。这种算法的时间复杂度为O(m * n),显著优于指数级的穷举搜索方法。
最长公共子序列(Longest Common Subsequence,LCS)问题是一个经典的计算机科学问题,主要涉及字符串处理和动态规划算法。在本场景中,我们使用C#编程语言来解决这个问题。C#是一种多范式编程语言,广泛应用于开发...
最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的字符串问题,主要涉及算法设计与分析,特别是在动态规划领域的应用。在这个问题中,我们需要找到两个或多个字符串之间的最长子序列,这...
在求解最长公共子序列时,我们通常使用二维数组来存储子问题的解,这种方法也被称为动态规划表格。 假设我们有两个字符串 `X` 和 `Y`,长度分别为 `m` 和 `n`,我们可以创建一个大小为 `m+1` by `n+1` 的二维数组 `...
动态规划算法求最长公共子序列 动态规划算法是一种常用的算法思想,它通过将复杂的问题分解成多个小问题,并将这些小问题的解组合起来,来解决复杂的问题。在这里,我们使用动态规划算法来求解最长公共子序列问题。...
动态规划解决最长公共子序列问题,即寻找两个序列中公共的序列中的最长的那个,结果不唯一,只能输出一个最长公共子序列,并不能生成所有的; 可视化多文档,手动输入两个子序列,显示动态规划算法的解决表格,箭头...
最长公共子序列(动态规划) 实验数据:input.txt X={A,B,C,B,D,A,B}; Y={B,D,C,A,B,A} ——要求给出X、Y的最长公共子序列Z,程序运行结束时,将计算结果输出到文件output.txt中。输出文件中包含问题的答案:找不到...
实验报告的主题是“算法设计与分析”,关注的是使用动态规划解决最长公共子序列(Longest Common Subsequence, LCS)的问题。动态规划是一种有效的方法,它适用于具有最优子结构和子问题重叠性质的问题。在本实验中...
最长公共子序列(lcs)使用动态规划解决采用c++编写
【最长公共子序列算法】 最长公共子序列(Longest Common Subsequence, ...在这个实验中,我们学习了如何运用动态规划来找到两个字符串的最长公共子序列,加深了对动态规划思想的理解,并通过实际编程实现了这一过程。
利用动态规划 实现排序 找到最长公共工子序列
动态规划是一种强大的算法思想,广泛应用于计算机科学,特别是在解决最优化问题时,如寻找最长公共子序列(Longest Common Subsequence, LCS)。本主题聚焦于使用动态规划方法求解最长公共子序列问题,并通过C++语言...
总的来说,动态规划和KR算法都是求解最长公共子序列的有效方法,它们各有特点,适用于不同的编程环境和需求。而KMP算法则专注于高效的字符串匹配,虽然与LCS问题不是直接相关,但在字符串处理领域中同样重要。
动态规划法求解最长公共子序列问题与0-1背包问题 本实验报告旨在通过动态规划法解决最长公共子序列问题和0-1背包问题,以深入理解动态规划方法的思想、求解策略及步骤。 实验目的 * 理解动态规划方法的核心思想和...
最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的字符串问题,主要涉及算法设计和实现,特别是在动态规划领域的应用。在这个问题中,目标是找到两个或多个序列之间的最长子序列,这个子...