杭电1503_输出最长公共子序列

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1503

题目大意:给你两个字符串, 让你合并两个字符串,每个字符串里的字符相对位置不改变,字符可以共用, 输出最短的目标字符串

思路:先求出最长公共子序列的长度, 再倒序,求出一条最长子字符串,每个字符记录各在s1 和 s2 的位置,然后输出。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cstdlib>
 6 #include <cmath>
 7 #include <set>
 8 #include <map>
 9 #include <vector>
10 using namespace std;
11 
12 int max(int a, int b)
13 {
14     return a > b ? a : b;
15 }
16 struct node
17 {
18     int a1, a2;
19 }a[110];//记录s1 和 s2 第 i 个相同字母分别在s1(a1) 和 s2(a2) 的位置
20 int main()
21 {    
22     char s1[110], s2[110], s[210]; //s为目标字符串
23     int dp[110][110], i, j;//dp 用来最长公共子序列
24     while(~scanf("%s %s", s1 + 1, s2 + 1))
25     {
26         strcpy(s, "");
27         int l1 = strlen(s1 + 1), l2 = strlen(s2 + 1);
28         memset(dp, 0, sizeof(dp));
29         for(i = 1; i <= l1; i++)
30         {
31             for(j = 1; j <= l2; j++)
32             {
33                 dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
34                 if(s2[j] == s1[i])
35                     dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);//求最长公共子序列
36             }
37         }
38         int k = 0, mm = dp[l1][l2], ii = l1 + 1, jj = l2 + 1;
39         for(i = l1; i > 0; i--)//倒序
40         {
41             for(j = l2; j > 0; j--)
42             {     
43                 if(i < ii && j < jj){//注意, WA 了一发
44                     if(s1[i] == s2[j]) { //s1 和 s2 前一个相同的字母i, j 应该分别在此位置i, j 的前面     
45                         if(dp[i][j] == dp[i - 1][j - 1] + 1 && dp[i][j] == mm)
46                         {
47                             k++;
48                             a[k].a1 = i, a[k].a2 = j;
49                             mm--;
50                             ii = i, jj = j;
51                         }
52                     }
53                 }                
54                 if(mm == 0)
55                     break;
56             }
57         }
58         i = 1, j = 1;
59         int t = -1;
60         while(k > 0)
61         {
62             while(i < a[k].a1)
63             {
64                 s[++t] = s1[i];
65                 i++;
66                 
67             }
68             while(j < a[k].a2)
69             {
70                 s[++t] = s2[j];
71                 j++;
72             }
73             s[++t] = s1[i];
74             i++, j++;
75             k--;
76         }
77         while(i <= l1){
78             s[++t] = s1[i];
79             i++;            
80         }
81         while(j <= l2){
82             s[++t] = s2[j];
83             j++;
84         }
85         s[++t] = '\0';
86         cout << s << endl;
87     }
88     return 0;
89 }

 

posted @ 2016-05-20 21:32  海无泪  阅读(159)  评论(0编辑  收藏  举报