最长公共子序列

参考博客:

 http://www.cnblogs.com/sasuke-/p/5396843.html

http://www.cnblogs.com/huangxincheng/archive/2012/11/11/2764625.html

理解好这张图。

就是开个数组flag来判断每个点是怎么更新的,因为箭头只有三个方向,输出路径时只需要找斜着的就行了。

输出路径的代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn = 10;
 7 char s[maxn], t[maxn],re[maxn];
 8 int dp[maxn][maxn],flag[maxn][maxn];
 9 int cnt;
10 
11 void print(int x, int y)
12 {
13     if (x == 0 || y == 0) {
14 
15         for (int i = cnt-1; i >= 0; i--)
16             cout << re[i];
17         cout << endl;
18         return;
19     }
20     if (flag[x][y] == 2) {
21         re[cnt++] = s[x];
22         print(x - 1, y - 1);
23     }if (flag[x][y] == 1) {
24         print(x - 1, y);
25     }
26     else if(flag[x][y]==3)
27     {
28         print(x, y - 1);
29     }
30 }
31 
32 int main()
33 {
34     while (scanf("%s%s",s+1,t+1)==2)
35     {
36         memset(re, '', sizeof(re));
37         cnt = 0;
38         int lens = strlen(s + 1);
39         int lent = strlen(t + 1);
40 
41         for (int i = 0; i <= lens; i++) dp[i][0] = 0;
42         for (int j = 0; j <= lent; j++) dp[0][j] = 0;
43         dp[0][0] = 0;
44 
45         for (int i = 1; i <= lens; i++)
46         {
47             for (int j = 1; j <= lent; j++)
48             {
49                 if (s[i] == t[j]) {
50                     dp[i][j] = dp[i - 1][j - 1] + 1;
51                     flag[i][j] = 2;
52                 }
53                 else if (dp[i - 1][j] >=dp[i][j - 1]) {
54                     dp[i][j] = dp[i - 1][j];
55                     flag[i][j] = 1;
56                 }
57                 else {
58                     dp[i][j] = dp[i][j-1];
59                     flag[i][j] = 3;
60                 }
61             }
62         }
63         cout << dp[lens][lent] << endl;
64         print(lens, lent);
65 
66     }
67     return 0;
68 }
原文地址:https://www.cnblogs.com/zxhyxiao/p/7264692.html