SPOJ33&POJ1934 Trip LCS
题目传送门:https://www.luogu.org/problemnew/show/SP33
题目大意:给出两个字符串,求其LCS(最长公共子序列)的长度与具体方案(相同的串算作同一方案)。数据组数$\leq 10$,字符串长度$\leq 80$,方案数$\leq 1000$
本来以为这是一道LCS水题,结果超级low的各种输出方案的方法TLE到怀疑人生
于是一个高大上的输出方法出现(借鉴于https://blog.csdn.net/gg_gogoing/article/details/41170117)
多开两个辅助数组$f_{i,j}$与$g_{i,j}$代表$s1$与$s2$从第$1$个字符到第$i$个字符中字符$j$($a$对应$0$,$b$对应$1$,以此类推)最后一次出现的位置,计算完这两个数组之后,进行递归输出,同时使用枚举法,从后往前一个一个枚举当前位置可填的字母。
设$dfs( a , b , c)$表示当前$s1$的长度为$a$,$s2$的长度为$b$,待枚举的字母数量为$c$时的枚举过程,枚举$0-25$,得到该字母的$f_{a,b}$与$g_{a,b}$,如果当$s1$长度为$f_{a,b}$,$s2$长度为$g_{a,b}$时的最长公共子序列长度正好为$c$,则$dfs(f_{a,b} - 1 , g_{a,b} - 1 , c - 1)$,枚举完第一位后即得到一种满足题意的字符串
为何这样子可以大量剪枝?举例:
$abcabcaa$
$acbacba$
上面是样例数据,最长公共子序列长度为$5$。考虑$dfs(7,6,5)$时枚举到$a$(字符串从$0$开始标号),此时$f = 7 , g = 6$,会进行$dfs(6,5,4)$。如果不考虑上述枚举,我们的可选方案有$(0,0)(0,3)(0,6)(3,0)(3,3)(3,6)(6,0)(6,3)(6,6)(7,0)(7,3)(7,6)$共$12$种,因为相同的串算作同一方案,由贪心可以知道$(7,6)$是当前的最优选择,可以包含其他的所有情况,所以只需要向$(7,6)$继续搜索即可。
#include<bits/stdc++.h> using namespace std; string s1 , s2; vector < string > s; ][] , last1[][] , last2[][] , cou; //last1、last2对应上面的f、g。 inline int max(int a , int b){ return a > b ? a : b; } void create(int a1 , int a2 , int num , string ss){ ){ s.push_back(ss); return; } ; i < ; i++) if(last1[i][a1] >= num && last2[i][a2] >= num && maxN[last1[i][a1]][last2[i][a2]] == num) create(last1[i][a1] - , last2[i][a2] - , num - , (char)('a' + i) + ss); //递归输出最重要的过程!!! } int main(){ ios::sync_with_stdio(); int T; for(cin >> T ; T ; T--){ memset(maxN , , sizeof(maxN)); memset(last1 , , sizeof(last1)); memset(last2 , , sizeof(last2)); cin >> s1 >> s2; ; i <= s1.size() ; i++) ; j <= s2.size() ; j++){ ] == s2[j - ]) maxN[i][j] = max(maxN[i][j] , maxN[i - ][j - ] + ); maxN[i][j] = max(maxN[i][j] , max(maxN[i - ][j] , maxN[i][j - ])); } //LCS DP求解 ; i <= s1.size() ; i++) ; j < ; j++) ] - 'a' == j) last1[j][i] = i; ]; ; i <= s2.size() ; i++) ; j < ; j++) ] - 'a' == j) last2[j][i] = i; ]; create(s1.size() , s2.size() , maxN[s1.size()][s2.size()] , ""); sort(s.begin() , s.end()); ; i < s.size() ; i++) cout << s[i] << endl; //输出 s.clear(); cout << endl; cou = ; } ; }
SPOJ33&POJ1934 Trip LCS的更多相关文章
- 【题解】POJ1934 Trip (DP+记录方案)
[题解]POJ1934 Trip (DP+记录方案) 题意: 传送门 刚开始我是这么设状态的(谁叫我DP没学好) \(dp(i,j)\)表示钦定选择\(i\)和\(j\)的LCS,然而你会发现这样钦定 ...
- poj1934 Trip【线性DP】【输出方案】
Trip Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3850 Accepted: 1030 Description ...
- $Poj1934\ Trip$ 线性$DP+$搜索
Luogu Description 爱丽丝和鲍伯想去度假,他们每个人都制定了一个参观城市的清单,该地区正好有26个城市,因此它们被编码为小写字母“a”到“z”.清单上可能重复出现某个城市.因为他们想一 ...
- POJ1934 Trip 题解
LCS 模板,但要输出具体方案,这就很毒瘤了. 神奇的预处理:fa[i][j]表示在 \(a\) 串的前 \(i\) 个字符中,字母表第 \(j\) 个字母最晚出现的位置,fb[i][j]同理. 这样 ...
- [POJ1934] Trip
问题描述 Alice and Bob want to go on holiday. Each of them has planned a route, which is a list of citie ...
- 常规DP专题练习
POJ2279 Mr. Young's Picture Permutations 题意 Language:Default Mr. Young's Picture Permutations Time L ...
- 题解 【POJ1934】 Trip
题目意思: 有两个字符串(长度\(<=80\)),按字典序输出它们的最长公共子串的所有情况. 解析 最长公共子序列的长度应该都没问题了吧...有问题请自行百度 但关键是要求出每种情况,还要按字典 ...
- Trip
Trip 给出一个长度为n序列\(\{a_i\}\),长度为m的序列\(\{b_i\}\),求它们的不同lcs序列按字典序输出,\(n,m\leq 80\),lcs不超过1000个,字符为26个小写字 ...
- 我的第一篇博客----LCS学习笔记
LCS引论 在这篇博文中,博主要给大家讲一个算法----最长公共子序列(LCS)算法.我最初接触这个算法是在高中学信息学竞赛的时候.那时候花了好长时间理解这个算法.老师经常说,这种算法是母算法,即从这 ...
随机推荐
- 如何判断一个 APP页面是否是H5页面
1.无网络断开网络,显示404或则错误页面的是H5 2.页面布局a.在手机设置.开发者选项中开启显示布局边界功能:b.进入应用查看布局边界:c.原生应用可以看到各个控件的布局边界,H5只有整个页面的一 ...
- loadrunner 运行场景-场景运行原理
运行场景-场景运行原理 by:授客 QQ:1033553122 运行原理 1 Remote Agent Dispatcher(Process) 运行Controller在负载机上开启应用程序. 2 ...
- React.js 新手教程
正如你能从标题猜到的,这篇文章的目标是给那些有很少编程经验的读者的.比如,像我这样的人:因为迄今为止,我才探索了编程世界6个月.所以,这将是一篇新手村教程! 你只需要拥有对 HTML 和 CSS 的理 ...
- window服务器上mongodb的安装与如何将mongodb设置为服务,为mongodb设置管理用户,mongodb连接字符串配置
最近公司有一个项目模块让用nosql-mongodb替换了,故,对mongodb做了一点研究,然后分享一下! 1.首先说一下安装时的坑 下载mongodb,如果你从官网下载,将会是一件很慢的事情,在公 ...
- Python之groupby
# -*- coding: utf-8 -*-"""Created on Sat Jun 30 10:09:47 2018测试分组groupby@author: zhen ...
- SQL alwayson 辅助接点查询统计信息“丢失”导致查询失败
ALWAYSON 出现以下情况已经2次了,记录下: DBCC 执行完毕.如果 DBCC 输出了错误信息,请与系统管理员联系. 消息 2767,级别 16,状态 1,过程 sp_table_statis ...
- cropper实现基本的裁剪图片并上传
使用cropper之前需要先引用 cropper.css 和 cropper.js cropper 官网:https://fengyuanchen.github.io/cropper/ cropper ...
- Xamarin入门,开发一个简单的练手APP
之前周末用Xamarin练手做了个简单APP,没有啥逻辑基本就是个界面架子,MVVM的简单使用,还有Binding,Command的简单使用,还有一个稍微复杂点两个界面交互处理(子页面新增后关闭,父页 ...
- Nginx 错误日志配置
1.Nginx错误日志信息介绍: error_log的语法格式及参数说明: error_log file level; 关键字 日志文件 错误日志级别 其中,关键字 ...
- 使用parted创建gpt大分区例子
[root@VM000000518 ~]# parted /dev/xvde GNU Parted 2.1 Using /dev/xvde Welcome to GNU Parted! Type 'h ...