36-最长公共子序列
内存限制:64MB
时间限制:3000ms
Special Judge: No
accepted:18
submit:38
题目描述:
咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列。
tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
输入描述:
第一行给出一个整数N(0<N<100)表示待测数据组数 接下来每组数据两行,分别为待测的两组字符串。每个字符串长度不大于1000.
输出描述:
每组测试数据输出一个整数,表示最长公共子序列长度。每组结果占一行。
样例输入:
2 asdf adfsd 123abc abc123abc
样例输出:
3 6
分析:
①、类似于这种最长字串问题需要以一个串作为基串,另一个串则从左到右计算对应该位置的最大长度
②、即就是局部最优的情况下累积,就是全局最优
③、所以,以一个二维数组作为DP数组,我们要做的就是根据状态方程得出最大值
核心代码(模板):
1 for(int i = 1; i <= len1; ++ i) 2 { 3 for(int j = 1; j <= len2; ++ j) 4 { 5 if(s1[i] == s2[j]) dp[i][j] = dp[i-1][j-1] + 1; 6 else dp[i][j] = max(dp[i][j-1], dp[i-1][j]); 7 } 8 }
C/C++代码实现(AC):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <queue> 9 #include <set> 10 11 using namespace std; 12 const int MAXN = 1010; 13 int dp[MAXN][MAXN]; 14 15 int main() 16 { 17 int t; 18 scanf("%d", &t); 19 while(t --) 20 { 21 char s1[MAXN], s2[MAXN]; 22 int len1, len2; 23 memset(dp, 0, sizeof(dp)); 24 scanf("%s%s", s1 + 1, s2 + 1); 25 len1 = strlen(s1 + 1), len2 = strlen(s2 + 1); 26 27 for(int i = 1; i <= len1; ++ i) 28 { 29 for(int j = 1; j <= len2; ++ j) 30 { 31 if(s1[i] == s2[j]) 32 dp[i][j] = dp[i-1][j-1] + 1; 33 else 34 dp[i][j] = max(dp[i-1][j], dp[i][j-1]); 35 } 36 } 37 38 printf("%d ", dp[len1][len2]); 39 } 40 return 0; 41 }