转自: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。

 // File Name: 1934.cpp
// Author: Missa_Chen
// Created Time: 2013年07月07日 星期日 20时21分33秒 #include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <cstdlib>
#include <vector>
#include <time.h> using namespace std;
const int maxn = ;
int dp[maxn][maxn];
int last1[maxn][], last2[maxn][];
set <string> ans;
char tmp[maxn];
void dfs(int s1, int s2, int len)
{
if (len <= )
{
ans.insert(tmp);
return ;
}
if (s1 > && s2 > )
{
for (int i = ; i < ; ++i)
{
int t1 = last1[s1][i];
int t2 = last2[s2][i];
if (dp[t1][t2] == len)
{
tmp[len - ] = 'a' + i;
dfs(t1 - , t2 - , len - );
}
}
}
return ;
}
void LCS(string s1, string s2)
{
memset(dp, , sizeof(dp));
for (int i = ; i <= s1.size(); ++i)
{
for (int j = ; j <= s2.size(); ++j)
{
if (s1[i - ] == s2[j - ])
dp[i][j] = dp[i - ][j - ] + ;
else dp[i][j] = max(dp[i - ][j], dp[i][j - ]);
}
}
}
void solve(string s1, string s2)
{
memset(last1, , sizeof(last1));
memset(last2, , sizeof(last2));
for (int i = ; i <= s1.size(); ++i)
{
for (int j = ; j < ; ++j)
last1[i][j] = last1[i - ][j];
last1[i][s1[i - ] - 'a'] = i;
}
for (int i = ; i <= s2.size(); ++i)
{
for (int j = ; j < ; ++j)
last2[i][j] = last2[i - ][j];
last2[i][s2[i - ] - 'a'] = i;
}
tmp[dp[s1.size()][s2.size()]] = '\0';
dfs(s1.size(), s2.size(), dp[s1.size()][s2.size()]);
for (set <string> :: iterator it = ans.begin(); it != ans.end(); ++it)
cout <<*it<<endl;
}
int main()
{
string s1, s2;
while (cin >> s1 >> s2)
{
LCS(s1, s2);
solve(s1, s2);
}
return ;
}

poj 1934(LCS)的更多相关文章

  1. [POJ 1934] Trip

    [题目链接] http://poj.org/problem?id=1934 [算法] 先用dp求出LCS,然后搜索即可,注意加上一些剪枝 [代码] #include <algorithm> ...

  2. POJ 2250(LCS最长公共子序列)

    compromise Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u   Descri ...

  3. poj 2264(LCS)

    Advanced Fruits Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2158   Accepted: 1066   ...

  4. POJ 2217 LCS(后缀数组)

    Secretary Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1655   Accepted: 671 Descript ...

  5. $2019$ 暑期刷题记录1:(算法竞赛DP练习)

    $ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...

  6. POJ 1159 回文串-LCS

    题目链接:http://poj.org/problem?id=1159 题意:给定一个长度为N的字符串.问你最少要添加多少个字符才能使它变成回文串. 思路:最少要添加的字符个数=原串长度-原串最长回文 ...

  7. LCS POJ 1458 Common Subsequence

    题目传送门 题意:输出两字符串的最长公共子序列长度 分析:LCS(Longest Common Subsequence)裸题.状态转移方程:dp[i+1][j+1] = dp[i][j] + 1; ( ...

  8. hdu 1513 && 1159 poj Palindrome (dp, 滚动数组, LCS)

    题目 以前做过的一道题, 今天又加了一种方法 整理了一下..... 题意:给出一个字符串,问要将这个字符串变成回文串要添加最少几个字符. 方法一: 将该字符串与其反转求一次LCS,然后所求就是n减去 ...

  9. POJ 2250 Compromise(LCS)

    POJ 2250 Compromise(LCS)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87125#proble ...

随机推荐

  1. close和shutdown的区别

    转的,没验证 close(sock_fd)会把sock_fd的内部计数器减1当sock_fd的内部计数器为0时, 才调用shutodwn(), 并最终释放文件描述符调用shutdown()只是进行了T ...

  2. GRID用法(取行、列值;定位选中某行等等)

    Delphi Cxgrid获取选中行列,排序规则,当前正在编辑的单元格内的值 cxGrid1DBTableView1.Controller.FocusedRowIndex 当前行号 cxGrid1DB ...

  3. POJ1811 Prime Test(miller素数判断&&pollar_rho大数分解)

    http://blog.csdn.net/shiyuankongbu/article/details/9202373 发现自己原来的那份模板是有问题的,而且竟然找不出是哪里的问题,所以就用了上面的链接 ...

  4. 深入浅出ES6(十七):展望未来

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 出于对文章长度的考虑,我们还保留了一些尚未提及的新特性,在最后的这篇文章中我会集 ...

  5. App接口设计1

    http://blog.csdn.net/newjueqi/article/details/44062849 http://www.tuicool.com/articles/YNZBna http:/ ...

  6. http协议本身能获取客户端Mac地址问题

    http 位于网络应用程 应用层 会话层 表示层 传输层 网络层 数据链路层 物理层 数据在最高层开始传输 没经历下面一层加一层的头,然后传入目的电脑再进行一层层的解刨,所以http本来没有mac而接 ...

  7. uva 12589 - Learning Vector

    思路: 容易知道加向量的顺序是按向量斜率的大小顺序来的.由于数据不是很大,可以用背包解决!! dp[i][j]:加入最大面积为i时,加入了j个向量. 代码如下: #include<iostrea ...

  8. 离开csdn来到blog园

    csdn里没有限制阅读访问的功能,所以我选择来到cnblog 但是不得不说,cnblog做的界面很丑,我个人很不喜欢,但是没办法

  9. iOS开发--即时通讯常用第三方库

    前言 自毕业到现在,从事iOS即时通讯开发已经1年半之久.主要负责Allure开发,目前已上架,可以在苹果商店搜素Allure.Allure模仿微信的交互和设计效果,已经实现微信的大部分功能. 在这里 ...

  10. Android笔记——简单解析XML

    两部分,Xml资源文件和Java对Xml解析的实现 ----------------------------------------------------------- 版权声明:本文为博主原创文章 ...