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。
// 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)的更多相关文章
- [POJ 1934] Trip
[题目链接] http://poj.org/problem?id=1934 [算法] 先用dp求出LCS,然后搜索即可,注意加上一些剪枝 [代码] #include <algorithm> ...
- POJ 2250(LCS最长公共子序列)
compromise Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Descri ...
- poj 2264(LCS)
Advanced Fruits Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2158 Accepted: 1066 ...
- POJ 2217 LCS(后缀数组)
Secretary Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1655 Accepted: 671 Descript ...
- $2019$ 暑期刷题记录1:(算法竞赛DP练习)
$ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...
- POJ 1159 回文串-LCS
题目链接:http://poj.org/problem?id=1159 题意:给定一个长度为N的字符串.问你最少要添加多少个字符才能使它变成回文串. 思路:最少要添加的字符个数=原串长度-原串最长回文 ...
- LCS POJ 1458 Common Subsequence
题目传送门 题意:输出两字符串的最长公共子序列长度 分析:LCS(Longest Common Subsequence)裸题.状态转移方程:dp[i+1][j+1] = dp[i][j] + 1; ( ...
- hdu 1513 && 1159 poj Palindrome (dp, 滚动数组, LCS)
题目 以前做过的一道题, 今天又加了一种方法 整理了一下..... 题意:给出一个字符串,问要将这个字符串变成回文串要添加最少几个字符. 方法一: 将该字符串与其反转求一次LCS,然后所求就是n减去 ...
- POJ 2250 Compromise(LCS)
POJ 2250 Compromise(LCS)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87125#proble ...
随机推荐
- 使用fwrite()函数和fprintf()函数输出数据到文件时的区别
使用书上的一个课后题为例 有5个学生,每个学生有3门课的成绩,从键盘输入学生数据(包括学号,姓名,3们课程成绩),计算出每个学生的平均成绩,将原有数据和计算出的平均分数存放在磁盘文件“stud”中. ...
- [转载]Thread.Sleep(0)妙用
原文地址:http://blog.csdn.net/lgstudyvc/article/details/9337063 来自本论坛: 我们可能经常会用到 Thread.Sleep 函数来使线程挂起一段 ...
- Excel每隔两行自动求和一次怎么操作?
今天ytkah得到一份数据,要求进行统计分析,由于是原始数据,还没处理过,数据量有点大,如下图所示(Excel每隔两行自动求和),每天的数字由两项组成,男生的人数.消费值和女生的人数和消费值,数字都在 ...
- Unity动态加载和内存管理(三合一)
原址:http://game.ceeger.com/forum/read.php?tid=4394#info 最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Re ...
- mysql关联修改SQL及long与datetime类型相互转换
1.关联修改 #解决思路 UPDATE tb1,tb2 SET tb1.address=tb2.address WHERE tb1.name=tb2.name UPDATE car c,tmpcolo ...
- jQuery对象和javascript对象互换
jquery变js var obj=$("dom"); 或 var obj=jQuery("dom"); js 变 jquery var $jobj=$(obj ...
- 控制台应用程序的Main方法
总结一下Main方法规则: 1.Main 方法名大小写有规范. 2.Main 方法返回类型只有 void.int两种返回类型. 3.Main 方法的参数可以是string[] args,也可以为空,只 ...
- Linux:chmod -R 777 * 是什么意思?
首先,chmod命令是linux上用于改变权限的命令,-R 是递归遍历子目录,因为你要操作的文件使用的*通配符.777,第一个7代表文件所属者的权限,第二个7代表文件所属者所在组的权限,第三个7代表其 ...
- 545C. Woodcutters
题目链接 题意: n个树,在x1,x2,...,xn的位置,树的高度依次是h1,h2,...,hn 求的是当把树砍倒时候,不占用相邻树的位置,最大砍树个数 可向左 向右砍,即树向左向右倒,很显然 当树 ...
- jenkins创建git任务连接时遇到的问题
jenkins 创建任务后 配置 git时 报错 Jenkins Host key verification failed jenkins: Failed to connect to reposito ...