定义

longest common subsequence:给定两个序列S1和S2,求二者公共子序列S3的最长的长度。

//注意不是最大公共子串

分析

这个问题可以按照序列的长度来划分状态,也就是S1的前i个字符和S2的前j个字符的最长公共子序列长度,记为lcs[i][j]。

如果S1的第i项,和S2的第j项相同,那么S1[i]与S2[j]作为公共子序列的末尾,则

lcs[i][j] = lcs [ i-1 ] [ j-1 ]+1

也可以不让S1[i]与S2[j]作为公共子序列的末尾,则

lcs[i][j] = max(lcs[ i ] [ j -1 ], lcs[ i-1 ] [ j ])

最长公共子序列 LCS

注意:这种方法考虑的是到某一位(i, j)为止,而不一定是以它结尾

 

关于不相等的转移方程:可以这么理解:既然两个位置不等,那么就求这两个位置之前的一个最大值,而显然,越靠近这两个位置的值越大,那么就取各自减1的位置就行了。

这个不相等时的转移方程是一定要有的,因为不像最大公共子串维护了一个最大值,一旦不相等了不需要看前面的累计,不需要任何处理,继续往下走就行;这里是求子序列,序列是可以不连续的,所以必须每个点都要存值。

int dp[10][10];

int main(){
	
	string a, b;
	cin >> a >> b;
	int lena = a.length();
	int lenb = b.length();
	for(int i = 0; i < lena; i++){
		for(int j = 0; j < lenb; j++){
			if(a[i] == b[j])
				dp[i+1][j+1] = dp[i][j] + 1;
			else 
				dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);
		}
	}
    //输出dp数组,最后一个值即为答案
	for(int i = 1; i < lena+1; i++){
		for(int j = 1; j < lenb+1; j++)
			cout << dp[i][j] << " ";
		cout << endl;
	}
	return 0;
}

 

 

相关文章:

  • 2021-06-18
  • 2022-02-10
  • 2021-09-22
  • 2021-06-18
猜你喜欢
  • 2021-05-20
  • 2021-04-09
  • 2022-01-24
  • 2022-01-20
相关资源
相似解决方案