Common Subsequence
Time Limit: 1000MS
|
|
Memory Limit: 10000K
|
Total Submissions: 17815
|
|
Accepted: 6847
|
Description
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, ..., xm > another sequence Z = < z1, z2, ..., zk > is a subsequence of X if there exists a strictly increasing sequence < i1, i2, ..., ik > of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
Input
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.
Output
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
Source
Southeastern Europe 2003
解题思路:这是个求最长公共子序列长度的问题,首先要知道子序列不一定必须是连续的,即中间可以被其他字符分开,但它们的顺序必须是正确的。另外,最长公共子序列不一定只有一个,而我们要寻找的是其中之一就够了。
此题是典型的动态规划问题,我们先考虑输入序列S1和S2的前缀序列:
设c[i, j] = |LCS(S1[1..i], S2[1..j])|,则有c[m, n] = |LCS(S1, S2)|。
仔细观察我们可以发现递推式:
c[i, j] = c[i-1, j-1] + 1, 如果S1[i] = S2[j]
=max{c[i-1, j], c[i, j-1]}, 如果S1[i] != S2[j]
因此我们获得了该问题的最优子结构特性,即一个最优解决方案包含了子问题的最优解决方案,也就是说,如果CS=LCS(S1, S2),则CS的任何前缀子串必是S1和S2的某个前缀的最长公共子序列。
通过分析我们还可以知道该递归包含了重复的子问题,因此我们就可以使用DP来降低复杂度。
计算最长公共子序列长度的DP算法如下:
初始化c[i, j],0<=i<=m, 0<=j<=n
for i=1 to m do
for j=1 to n do
if S1[i]==S2[j] then
c[i, j] = LCS[S1, S2, i-1, j-1] + 1 (即c[i-1, j-1] + 1)
else if c[i-1, j] <= c[i, j-1] then
c[i, j] = c[i, j-1]
else
c[i, j] = c[i-1, j]
代码如下:
#include <iostream>
#include <string>
std::string str1;
std::string str2;
int num[256][256]; //数组开低了会出现Runtime Error
int lcs(std::string s1, std::string s2, int m, int n)
{
for(int i=1; i<=m; i++)//此处需从1开始,因为下面循环有num[i-1][j-1]是最小的
{
for(int j=1; j<=n; j++)
{
if(s1[i-1] == s2[j-1])
{
num[i][j] = num[i-1][j-1] + 1;
}
else
{
if(num[i][j-1] < num[i-1][j])
{
num[i][j] = num[i-1][j];
}
else
{
num[i][j] = num[i][j-1];
}
}
}
}
return num[m][n];
}
int main()
{
int len1, len2;
while(std::cin>>str1>>str2)
{
memset(num, 0, sizeof(num));
len1 = str1.length();
len2 = str2.length();
int out = lcs(str1,str2,len1,len2);
std::cout<<out<<std::endl;
}
system("pause");
return 0;
}
分享到:
相关推荐
### 最长公共子序列(Longest Common Subsequence, LCS) #### 定义与概念 最长公共子序列问题(LCS)是计算机科学中的一个经典问题,它涉及到在两个或多个序列中寻找最长的相同子序列。这里所说的“子序列”并不...
动态规划 poj Common Subsequence c++ cpp文件
最大连续子序列和(Maximal Contiguous Subsequence Sum,简称MCSS)问题是一个经典的计算机科学问题,主要涉及算法设计和分析,尤其是动态规划和分治策略。在这个问题中,目标是从一个整数数组中找到一个子序列,...
Pku acm 第1458题 Common Subsequence 代码,有详细的注释,动态规划
本项目聚焦于一个经典问题——计算两个字符串的最大公共子序列(Longest Common Subsequence,LCS)。这是一个在序列比对、文本编辑距离等领域有广泛应用的问题。本压缩包中的源码提供了使用动态规划方法解决这一...
c语言入门 c语言_leetcode题解之1143_longest_common_subsequence
在`max-subsequence-sum.js`这个文件中,很可能包含的就是使用JavaScript实现的最大子序列和的示例代码,比如Kadane's Algorithm的实现。通过阅读和理解这个文件,你可以更好地掌握这个问题的解决方案,并将其应用到...
标题“POJ2533-Longest Ordered Subsequence”是指北京大学在线判题系统POJ上的一道编程题目,其核心任务是寻找一个序列中最长的有序子序列。描述中的“解题报告+AC代码”表明这个压缩包包含了对这道问题的解答思路...
在计算机科学中,最大子序列和(Maximum Subsequence Sum,MSS)问题是一个经典的问题,主要涉及在数组或序列中找到具有最大和的连续子序列。这个问题在算法设计和分析中有着广泛的应用,例如在股票交易策略、数据...
最长公共子序列问题,动态规划法
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一种经典的问题,主要涉及字符串或序列的比较和分析。这个问题在文本编辑器的差异计算、生物信息学的DNA序列比对以及程序代码的相似性检测等多...
北大POJ2533-Longest Ordered Subsequence【O(nlogn)】
最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的问题,主要应用于文本比较、生物信息学等领域。在这个问题中,我们不考虑子序列的顺序,只关心两个序列中是否存在相同的字符,而这些...
北大POJ2533-Longest Ordered Subsequence【O(n^2)】
poj经典动态规划题目解题报告,包括经典的动态规划题目20多道,可以作为学习动态规划系统的资料,包括题目: Pku acm 1179 Polygon Pku acm 1125 Stockbroker Grapevine Pku acm 1160 post office Pku ...
它与最长公共子序列(Longest Common Subsequence,LCS)不同,后者不要求子序列在原字符串中是连续的。 要解决这个问题,我们可以使用动态规划的方法。动态规划是一种通过将大问题分解为更小的子问题来求解的方法...
575-最长理想子序列 [longest-ideal-subsequence].html
6. 1458 Common Subsequence:寻找两个字符串的最长公共子序列,经典动态规划问题。 7. 1953 World Cup Noise:可能需要计算某种状态的最大可能性。 其次,模拟题通常是指通过精确复制问题的逻辑来求解的题目,这类...
c c语言_leetcode题解之0300_longest_increasing_subsequence