36-最长公共子序列
内存限制:64MB
时间限制:3000ms
Special Judge: No
accepted:18
submit:38
题目描述:
咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列。
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 }
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\n", dp[len1][len2]);
39 }
40 return 0;
41 }
Aspire to inspire until I expire