最长公共子序列
参考博客:
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, '\0', 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 }