最长公共子序列(Longest Common Sequence,LCS)的问题描述为:
给定两个字符串(或数字序列)A和B,求一个字符串,使得这个字符串是A和B的最长公共部分(子序列可以不连续)。
样例输入
abcfbc abfcab
programming contest
abcd mnp
样例输出
4
2
0
思路:
令 d p [ i ] [ j ] dp[i][j] dp[i][j]表示字符串A的i号位和字符串B的j号位之前的LCS长度。(下标从1开始)。
那么可以根据 A [ i ] A[i] A[i]和 B [ j ] B[j] B[j]的情况分为两种决策:
- 若 A [ i ] = B [ j ] A[i]=B[j] A[i]=B[j],则 d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 dp[i][j] = dp[i-1][j-1] + 1 dp[i][j]=dp[i−1][j−1]+1;
- 若 A [ i ] ! = B [ j ] A[i]!=B[j] A[i]!=B[j],则 d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) dp[i][j] = max(dp[i-1][j],dp[i][j-1]) dp[i][j]=max(dp[i−1][j],dp[i][j−1])。
#include <iostream>
using namespace std;
const int maxn = 101;
string a, b;
int dp[maxn][maxn];
int n, m;
int search()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if(a[i]==b[j]){
dp[i][j] = dp[i-1][j-1] + 1;
}else{
dp[i][j] = max(dp[i][j-1],dp[i-1][j]);
}
}
}
return dp[n][m];
}
int main()
{
while (cin >> a >> b)
{
n = a.size();
m = b.size();
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
dp[i][j] = 0;
}
}
a = " " + a; //让数组的真实下标变为从1开始
b = " " + b;
cout << search() << endl;
}
return 0;
}