zoukankan      html  css  js  c++  java
  • 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()]] = '';
    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 }
  • 相关阅读:
    网络编程的基础
    day31作业
    异常处理其他内容
    异常处理的使用
    常见的异常种类
    ansible条件使用--实践
    Ansible的循环
    Ansible的条件语句
    ansibleplaybook的使用
    ansible官方文档翻译之变量
  • 原文地址:https://www.cnblogs.com/Missa/p/3176866.html
Copyright © 2011-2022 走看看