和最长公共子串区别的地方在于它的位置不要求是连续的。不过求解的思路和最长公共子串差不太多,同样用c[][]保存状态,但是转移方程为:
如果s1[i]==s2[j],则c[i][j]=c[i-1][j-1]+1
如果s1[i]!=s2[j],则c[i][j]=max{c[i-1][j],c[i][j-1]}
也就是,如果不相等,那么取max{去除s1当前字符的最长公共子串,去除s2当前字符的最长公共子串}
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <stdlib.h>
#define MAX_N 500
using namespace std;
int LCSe(char *s1,char *s2)
{
int len1,len2,i,j,maxlen=0;
int c[MAX_N][MAX_N]={0};
len1=strlen(s1);
len2=strlen(s2);
for(i=1;i<len1+1;i++)
{
for(j=1;j<len2+1;j++)
{
if(s1[i-1]==s2[j-1])
{
c[i][j]=c[i-1][j-1]+1;
}
else
{
c[i][j]=max(c[i-1][j],c[i][j-1]);
}
if(c[i][j]>maxlen)
{
maxlen=c[i][j];
}
}
}
return maxlen;
}
int main()
{
freopen("in.txt","r",stdin);
char str1[MAX_N],str2[MAX_N];
scanf("%s",str1);
scanf("%s",str2);
printf("%d\n",LCSe(str1, str2));
}