题目链接:http://noi.openjudge.cn/ch0206/1808/
总时间限制:
1000ms 内存限制: 65536kB-
描述
-
我们称序列Z = < z
1, z
2, ..., z
k >是序列X = < x
1, x
2, ..., x
m >的子序列当且仅当存在
严格上升 的序列< i
1, i
2, ..., i
k >,使得对j = 1, 2, ... ,k, 有x
ij = z
j。比如Z = < a, b, f, c > 是X = < a, b, c, f, b, c >的子序列。
现在给出两个序列X和Y,你的任务是找到X和Y的最大公共子序列,也就是说要找到一个最长的序列Z,使得Z既是X的子序列也是Y的子序列。
输入
- 输入包括多组测试数据。每组数据包括一行,给出两个长度不超过200的字符串,表示两个序列。两个字符串之间由若干个空格隔开。 输出
- 对每组输入数据,输出一行,给出两个序列的最大公共子序列的长度。 样例输入
-
abcfbc abfcab programming contest abcd mnp
样例输出
-
4 2
-
- /* 1.最优子问题 2.无后效性
- 动态规划的思路就是在满足上述2个条件下 找到另一种描述的形式 推出动态转移方程(当然很多题目没那么容易想出来- -)
- * dp[i][j]表示s1的前i个字符和s2的前j个字符的最大公共子列
- * 动态转移方程:
- if (p[i] == q[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]);
- */
- #include "iostream"
- #include "cstring"
- #include "algorithm"
- using namespace std;
- int main()
- {
- char p[201], q[201];
- int dp[201][201];
- while (cin >> p >> q) {
- memset(dp, 0, sizeof(dp));
- int lenP = strlen(p);
- int lenQ = strlen(q);
- for (int i = 0; i<lenP; i++)
- for (int j = 0; j < lenQ; j++) {
- if (p[i] == q[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]);
- }
- cout << dp[lenP][lenQ] << endl;
- }
- return 0;
- }