给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
比如两个串为:
abcicba
abdkscab
ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。
Input
第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000)
Output
输出最长的子序列,如果有多个,随意输出1个。
Input示例
abcicba abdkscab
Output示例
abca
李陶冶 (题目提供者)
C++的运行时限为:1000 ms ,空间限制为:131072 KB 示例及语言说明请按这里
先用LCS模版找出最长公共子序列的区间,再在si,ti里面逐渐比较区间具体位于那一段,然后逐渐缩小搜索范围当si=ti的时候储存起来。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1010;
char s[MAXN],t[MAXN];
int dp[MAXN+1][MAXN+1];//表示长度为i,j的最长公共子序列
char path[MAXN*10];//用来记录路径
void solve(int n,int m){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(s[i]==t[j]) dp[i+1][j+1]=dp[i][j]+1;//在si,ti后面都在家一个si+1,ti+1;
else dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]);
}
}
}
int main(){
memset(dp,0,sizeof(dp));
scanf("%s %s",s,t);
int len1=strlen(s);
int len2=strlen(t);
solve(len1,len2);
int i=len1-1,j=len2-1;
int k=0;
while(i>=0&&j>=0){
if(s[i]==t[j]){
path[k++]=s[i];
i--;
j--;
}
else if(dp[i+1][j]>=dp[i][j+1]) j--;//用来说明lcs位于那一段字符
else i--;
}
for(int i=k-1;i>=0;i--) printf("%c",path[i]);//应为i和j是反向记录所以反向输出
printf("\n");
return 0;
}