NOI:1808 公共子序列

题目链接: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


[cpp]  view plain  copy
  1. /* 1.最优子问题 2.无后效性 
  2.    动态规划的思路就是在满足上述2个条件下  找到另一种描述的形式 推出动态转移方程(当然很多题目没那么容易想出来- -) 
  3.  * dp[i][j]表示s1的前i个字符和s2的前j个字符的最大公共子列 
  4.  *  动态转移方程: 
  5.         if (p[i] == q[j]) 
  6.                     dp[i+1][j+1] = dp[i][j] + 1; 
  7.                 else 
  8.                     dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]); 
  9. */  
  10. #include "iostream"  
  11. #include "cstring"  
  12. #include "algorithm"  
  13. using namespace std;  
  14. int main()  
  15. {  
  16.     char p[201], q[201];  
  17.     int dp[201][201];  
  18.     while (cin >> p >> q) {  
  19.         memset(dp, 0, sizeof(dp));  
  20.         int lenP = strlen(p);  
  21.         int lenQ = strlen(q);  
  22.         for (int i = 0; i
  23.             for (int j = 0; j < lenQ; j++) {  
  24.                 if (p[i] == q[j])  
  25.                     dp[i+1][j+1] = dp[i][j] + 1;  
  26.                 else  
  27.                     dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);  
  28.             }  
  29.         cout << dp[lenP][lenQ] << endl;  
  30.     }  
  31.     return 0;  
  32. }  

你可能感兴趣的:(NOI,NOI)