题目:
最长公共子序列
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列。
tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。-
输入
-
第一行给出一个整数N(0<N<100)表示待测数据组数
接下来每组数据两行,分别为待测的两组字符串。每个字符串长度不大于1000.
输出
- 每组测试数据输出一个整数,表示最长公共子序列长度。每组结果占一行。 样例输入
-
2 asdf adfsd 123abc abc123abc
样例输出
-
3 6
-
第一行给出一个整数N(0<N<100)表示待测数据组数
这道题是典型的动态规划的题目:
AC代码是这样的:
#include <iostream>
using namespace std;
const int MAX = 1001;
int main()
{
int N;
cin >> N;
while(N--)
{
char s1[1001];
char s2[1001];
int *c = new int [MAX * MAX];
int i = 0;
int j = 0;
cin >> s1 >> s2;
for(i = 0; i < MAX * MAX; ++i)
{
c[i] = 0;
}
for(i = 0; s1[i] != '\0'; ++i)
{
for(j = 0; s2[j] != '\0'; ++j)
{
if(s1[i] == s2[j])
{
c[(i + 1) * MAX + j + 1] = c[i * MAX + j] + 1;
}
else
{
if(c[(i + 1) * MAX + j] > c[i * MAX + j + 1])
{
c[(i + 1) * MAX + j + 1] = c[(i + 1) * MAX + j];
}
else
{
c[(i + 1) * MAX + j + 1] = c[i * MAX + j + 1];
}
}
}
}
cout << c[i * MAX + j] << endl;
delete c;
}
return 0;
}
这道题不能用递归做,否则的话会超时。略坑。
还有就是,不知道是不是编译器的原因,我定义1001*1001的话,会栈溢出,运行会出错,所以就用了动态分配数组。new一个1001*1001的数组。
下面附上递归的代码:
#include <iostream>
using namespace std;
int max(int a, int b)
{
return a > b ? a : b;
}
int LCS(char *s1, char *s2, int length)
{
if(s1[0] == '\0' || s2[0] == '\0')
{
return length;
}
else
{
if(s1[0] == s2[0])
{
length = LCS(s1 + 1, s2 + 1, length) + 1;
}
else
{
length = max(LCS(s1 + 1, s2, length), LCS(s1, s2 + 1, length));
}
}
return length;
}
int main()
{
int N;
cin >> N;
while(N--)
{
char s1[1001];
char s2[1001];
int length = 0;
cin >> s1 >> s2;
length = LCS(s1, s2, length);
cout << length << endl;
}
return 0;
}
递归的比较好理解。就是不断的分层深入。