最长公共子序列LCS简介
2017-09-06 21:37
375 查看
算法简介
一个数列 ,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则称为已知序列的最长公共子序列。算法思想
貌似不难吧。。。动动脑筋。运用DP的思想,对于当前枚举到的两个数a[i],b[j],如果a[i]==b[j],那么f[i][j]=f[i-1][j-1]+1,否则就取f[i-1][j]和f[i][j-1]的最大值。
可以写出状态转移方程式:
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]);
划水
模板
#include<cstdio> #include<cstring> #include<algorithm> #define MAXN 1000 using namespace std; char s1[MAXN+5],s2[MAXN+5]; int f[MAXN+5][MAXN+5]; int main(){ scanf("%s%s",s1,s2); int n1=strlen(s1),n2=strlen(s2); memset(f,0,sizeof(f)); for (int i=1;i<=n1;i++) for (int j=1;j<=n2;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]); printf("%d\n",f[n1][n2]); return 0; }
算法拓展
某些题目可能要求你求出LCS。 此时我们可以把它往回倒推,比如像这样:int x=n,y=m,node=f[n][m]; while (x>0&&y>0){ if (s1[x-1]==s2[y-1]){//如果这两个相等 x--; y--; s[node-1]=s1[x]; node--;//往回退 } else//不相等就不取并调整 if (f[x-1][y]>f[x][y-1]) x--; else y--; }
还有些可能有三个数列,这时加一维即可。
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) for (int k=1;k<=l;k++) if (s1[i-1]==s2[j-1]&&s2[j-1]==s3[k-1]) f[i][j][k]=f[i-1][j-1][k-1]+1; else f[i][j][k]=max(max(f[i-1][j][k],f[i][j-1][k]),f[i][j][k-1]);
求LCS也一样:
int x=n,y=m,z=l,node=f[n][m][l]; while (x>0&&y>0&&z>0) if (s1[x-1]==s2[y-1]&&s2[y-1]==s3[z-1]){ x--; y--; z--; node--; s[node]=s1[x]; } else{ if (f[x][y][z]==f[x-1][y][z]) x--; if (f[x][y][z]==f[x][y-1][z]) y--; if (f[x][y][z]==f[x][y][z-1]) z--; }
相关文章推荐
- 最长公共子序列LCS和字符串编辑距离
- LCS最长公共子序列(最优线性时间O(n))
- 算法学习 - 最长公共子序列(LCS)C++实现
- LCS(最长公共子序列)、LIS(最长上升子序列)、LCIS(最长公共上升子序列)
- 最长公共子序列(LCS)
- 最长公共子序列(LCS)
- LCS最长公共子序列
- 最长公共子序列(LCS)
- 最长公共子序列(LCS)问题
- LCS问题及拓展:最长公共子序列和最长公共子串
- 关于输出多个LCS(最长公共子序列)的简单技巧
- LCS最长公共子序列~dp学习~4
- 最长公共子序列(LCS)问题--动态规划
- 动态规划算法解最长公共子序列LCS问题
- 最长公共子序列(LCS)
- 动态规划求解最长公共子序列(LCS)
- 51Nod 1006 最长公共子序列Lcs (输出)
- 求三个字符串的最长公共子序列LCS(A,B,C)
- 最长公共子序列(LCS)and最长上升子序列(LIS)
- 51Nod- 1006 最长公共子序列Lcs(动态规划)