求两个字符串的最长公共子序列长度。
输入格式:
输入长度≤100的两个字符串。
输出格式:
输出两个字符串的最长公共子序列长度。
输入样例1:
ABCBDAB
BDCABA
输出样例1:
4
输入样例2:
ABACDEF
PGHIK
输出样例2:
0
公共子序列:如果两个字符串包含共同的子序列,那么这个子序列就被称为公共子序列了。如样例中的ABCBDAB和BDCABA的公共子序列就有A、BD、BDAB等。而其中最长的子序列就是所谓的最长公共子序列(LCS)。当然,最长公共子序列也许不止一个,题目给的就是一个代表例子,它们的LCS为“BCBA”,“BCAB”,“BDAB”。
没系统学过这些算法思想真是难受,好多都想不到,除非那种明显的,比如斐波那契数列那样的,应该还是这方面做题少的原因。。
假设现在有两个字符串序列:X={x1,x2,…xi…xm},Y={y1,y2,…yj…yn}。如果知道了X={x1,x2,…xi-1}和Y={y1,y2,…yj-1}的最大公共子序列,那么后续的可以按递推的方法进行求解,就像斐波那契数列一样,知道了前两项,就能求后边的一项。如果xi==yj,其长度是len(L)+1。即序列{Xi,Yj}的最优解是由{xi-1,yj-1}求得的。如果不相等,则是前边所求的,{xi,yj-1}和{xi-1,yj}中的最大值,总之都是根据前边已知的解去求解未知的解,下边两种方式都可以,无非开始的编号不同
#include <iostream>
#include <string>
using namespace std;
int arr[105][105],len1,len2;
string s1,s2;
void DP(){
for(int i = 1;i<=len1;i++){
for(int j = 1;j<=len2;j++){
if(s1[i-1]==s2[j-1])
arr[i][j] = arr[i-1][j-1] + 1;
else
arr[i][j] = max(arr[i][j-1],arr[i-1][j]);
}
}
}
int main(){
getline(cin,s1);
getline(cin,s2);
len1 = s1.length();
len2 = s2.length();
DP();
cout << arr[len1][len2];
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int arr[105][105],len1,len2;
string s1,s2;
void DP(){
for(int i = 0;i<len1;i++){
for(int j = 0;j<len2;j++){
if(s1[i]==s2[j])
arr[i+1][j+1] = arr[i][j] + 1;
else
arr[i+1][j+1] = max(arr[i][j+1],arr[i+1][j]);
}
}
}
int main(){
//防止输入的字符串有空格
getline(cin,s1);
getline(cin,s2);
len1 = s1.length();
len2 = s2.length();
DP();
cout << arr[len1][len2];
return 0;
}