码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1503 LCS输出路径【dp】

时间:2017-08-26 23:33:23      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:image   while   space   div   class   回溯   char   names   技术分享   

hdu 1503

  不知道最后怎么输出,因为公共部分只输出一次。有人说回溯输出,感觉好巧妙!其实就是下图,输出的就是那条灰色的路径,但是初始时边界一定要初始化一下,因为最第一列只能向上走,第一行只能向左走。我用1表示向上走,2向左上方走,3向左走。

  刚开始输入字符串时有两种方法,直接输入;或从地址后一位输入,即此时数组起始编号为1。直接输入时,dp[i][j]表示的是以s1[i-1],s2[j-1]为结尾LCS,另一种则就是表示以s1[i],s2[j]为结尾的LCS。两者在路径输出时有些差别,以前感觉直接输出LCS长度后者方便,其实都一样。

技术分享

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAXN = 107;
 7 char s1[MAXN], s2[MAXN];
 8 int dp[MAXN][MAXN], flag[MAXN][MAXN];
 9 int len1, len2;
10 
11 void LCS()
12 {
13     memset(dp, 0, sizeof(dp));
14     for (int i = 0; i <= len1; i++) flag[i][0] = 1;
15     for (int i = 0; i <= len2; i++) flag[0][i] = 3;
16     for (int i = 1; i <= len1; i++) {
17         for (int j = 1; j <= len2; j++) {
18             if (s1[i - 1] == s2[j - 1]) {
19                 dp[i][j] = dp[i - 1][j - 1] + 1;
20                 flag[i][j] = 2;
21             }
22             else if (dp[i - 1][j] >= dp[i][j - 1]) {
23                 dp[i][j] = dp[i - 1][j];
24                 flag[i][j] = 1;
25             }
26             else {
27                 dp[i][j] = dp[i][j - 1], flag[i][j] = 3;
28             }
29         }
30     }
31 }
32 
33 void Print(int x, int y)
34 {
35     if (x == 0 && y == 0) return;
36     if (flag[x][y] == 2) {
37         Print(x - 1, y - 1);
38         cout << s1[x-1];
39     }
40     else if (flag[x][y] == 1) {
41         Print(x - 1, y);
42         cout << s1[x - 1];
43     }
44     else {
45         Print(x, y - 1);
46         cout << s2[y - 1];
47     }
48 }
49 
50 int main()
51 {
52     while (cin>>s1>>s2)
53     {
54         len1 = strlen(s1), len2 = strlen(s2);
55         LCS();
56         Print(len1, len2);
57         cout << endl;
58     }
59     return 0;
60 }

起始编号为1:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 const int MAXN = 107;
 6 int dp[MAXN][MAXN], flag[MAXN][MAXN];
 7 char s1[MAXN], s2[MAXN];
 8 int len1, len2;
 9 
10 void LCS()
11 {
12     for (int i = 0; i <= len1; i++) flag[i][0] = 1;
13     for(int i = 0; i <= len2; i++) flag[0][i] = 3;
14     for (int i = 1; i <= len1; i++) {
15         for (int j = 1; j <= len2; j++) {
16             if (s1[i] == s2[j])
17                 dp[i][j] = dp[i - 1][j - 1] + 1, flag[i][j] = 2;
18             else if (dp[i - 1][j] >= dp[i][j - 1])
19                 dp[i][j] = dp[i - 1][j], flag[i][j] = 1;
20             else dp[i][j] = dp[i][j - 1], flag[i][j] = 3;
21         }
22     }
23 }
24 
25 void Print(int x, int y)
26 {
27     if (x == 0 && y == 0) return;
28     if (flag[x][y] == 2) {
29         Print(x - 1, y - 1);
30         printf("%c", s1[x]);
31     }
32     else if (flag[x][y] == 1) {
33         Print(x - 1, y);
34         printf("%c", s1[x]);
35     }
36     else {
37         Print(x, y - 1);
38         printf("%c", s2[y]);
39     }
40     return;
41 }
42 
43 int main()
44 {
45     while (scanf("%s %s", s1 + 1, s2 + 1)==2)
46     {
47         len1 = strlen(s1 + 1), len2 = strlen(s2 + 1);
48         memset(dp, 0, sizeof(dp));
49         LCS();
50         Print(len1, len2);
51         printf("\n");
52     }
53     return 0;
54 }

 

hdu 1503 LCS输出路径【dp】

标签:image   while   space   div   class   回溯   char   names   技术分享   

原文地址:http://www.cnblogs.com/zxhyxiao/p/7436606.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!