知识点
最长公共子序列(Longest Common Subsequence),简称LCS问题。假设现在有两个序列X,Y。那么他们的子序列中相同且长度最大的子序列则称为X,Y的最长公共子序列。
问题链接
ALDS1_10_C:Longest Common Subsequence
问题内容
求两个字符中最长公共子序列
思路
利用斐波那契数列的递推关系,可以联想到。
当 Xi=Yj 时,当前的 LCS(i,j) 等于 Xi−1和Yj−1 时的LCS加上1。即 LCS(i,j)=LCS(i−1,j−1)+1 .
当 Xi≠Yj ,此时的 LCS(i,j) 等于 LCS(i−1,j) 和 LCS(i,j−1) 的最大值。
总结:
c[i][j]=⎧⎩⎨⎪⎪⎪⎪0c[i−1][j−1]+1max(c[i][j−1],c[i−1][j])===i=0或者j=0i,j>=0并且xi=yji,j>=0并且xi≠yj
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxx = 1010;
int c[maxx][maxx];
int lcs(char s1[],char s2[]) {
int m = strlen(s1), n = strlen(s2);
for (int i = 1; i <= m; i++)
c[i][0] = 0;
for (int i = 1; i <= n; i++)
c[0][i] = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (s1[i] == s2[j])
c[i+1][j+1] = c[i][j] + 1;
else
c[i+1][j+1] = max(c[i][j+1], c[i + 1][j]);
}
}
return c[m][n];
}
int main()
{
char s1[maxx], s2[maxx];
int t;
scanf("%d", &t);
for (int i = 0; i < t; i++) {
scanf("%s %s", s1, s2);
printf("%d\n",lcs(s1,s2));
}
return 0;
}