poj 1934(LCS)

转自:http://www.cppblog.com/varg-vikernes/archive/2010/09/27/127866.html

1)首先按照常规的方法求出最长公共子序列的长度
也就是用O(MN)的那个动态规划,结果放在二维数组dp里
dp[i][j] = { 字串a的1~i部分与字串b的1~j部分的最长公共子序列的长度 }
2)求辅助数组
last1[i][j] = { 到下标i为止,字符j在字串a中最后一次出现的下标 }
last2[i][j] = { 到下标i为止,字符j在字串b中最后一次出现的下标 }
3)枚举最长公共字串的每一个字符
从最后一个字符开始枚举
比如说现在枚举最后一个字符是'C'的情况。
那么 'CDCD' 与 'FUCKC' 这两个字串。
一共有 (0, 2) (0, 4)  (2, 2)  (2. 4) 这四种可能。
很明显前三个是可以舍弃的,因为第四个优于前三个,为后续的枚举提供了更大的空间。
last数组正好是用来做这个的。
4)排序输出
代码里用了stl的set。

 1 // File Name: 1934.cpp
 2 // Author: Missa_Chen
 3 // Created Time: 2013年07月07日 星期日 20时21分33秒
 4 
 5 #include <iostream>
 6 #include <string>
 7 #include <algorithm>
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cmath>
11 #include <queue>
12 #include <map>
13 #include <stack>
14 #include <set>
15 #include <cstdlib>
16 #include <vector>
17 #include <time.h>
18 
19 using namespace std;
20 const int maxn = 100;
21 int dp[maxn][maxn];
22 int last1[maxn][27], last2[maxn][27];
23 set <string> ans;
24 char tmp[maxn];
25 void dfs(int s1, int s2, int len)
26 {
27     if (len <= 0)
28     {
29         ans.insert(tmp);
30         return ;
31     }
32     if (s1 > 0 && s2 > 0)
33     {
34         for (int i = 0; i < 26; ++i)
35         {
36             int t1 = last1[s1][i];
37             int t2 = last2[s2][i];
38             if (dp[t1][t2] == len)
39             {
40                 tmp[len - 1] = 'a' + i;
41                 dfs(t1 - 1, t2 - 1, len - 1);
42             }
43         }
44     }
45     return ;
46 }
47 void LCS(string s1, string s2)
48 {
49     memset(dp, 0, sizeof(dp));
50     for (int i = 1; i <= s1.size(); ++i)
51     {
52         for (int j = 1; j <= s2.size(); ++j)
53         {
54             if (s1[i - 1] == s2[j - 1])
55                 dp[i][j] = dp[i - 1][j - 1] + 1;
56             else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
57         }
58     }
59 }
60 void solve(string s1, string s2)
61 {
62     memset(last1, 0, sizeof(last1));
63     memset(last2, 0, sizeof(last2));
64     for (int i = 1; i <= s1.size(); ++i)
65     {
66         for (int j = 0; j < 26; ++j)
67             last1[i][j] = last1[i - 1][j];
68         last1[i][s1[i - 1] - 'a'] = i;
69     }
70     for (int i = 1; i <= s2.size(); ++i)
71     {
72         for (int j = 0; j < 26; ++j)
73             last2[i][j] = last2[i - 1][j];
74         last2[i][s2[i - 1] - 'a'] = i;
75     }
76     tmp[dp[s1.size()][s2.size()]] = '\0';
77     dfs(s1.size(), s2.size(), dp[s1.size()][s2.size()]);
78     for (set <string> :: iterator it = ans.begin(); it != ans.end(); ++it)
79         cout <<*it<<endl;
80 }
81 int main()
82 {
83     string s1, s2;
84     while (cin >> s1 >> s2)
85     {
86         LCS(s1, s2);
87         solve(s1, s2);
88     }
89     return 0;
90 }

 

posted @ 2013-07-07 22:56  Missa  阅读(504)  评论(0编辑  收藏  举报