【题解】POJ1934 Trip (DP+记录方案)
【题解】POJ1934 Trip (DP+记录方案)
题意:
刚开始我是这么设状态的(谁叫我DP没学好)
\(dp(i,j)\)表示钦定选择\(i\)和\(j\)的LCS,然而你会发现这样钦定没什么用。
还不如当时初学者的时候的\(dp(i,j)\)表示考虑到\(i\)考虑到\(j\)的LCS...果然经典的是禁得起考验的...
考虑如何记录方案,第一个想法是直接暴力记录从哪转移的,但是这样显然不行。因为有很多重复的元素。
注意到题目保证本质不同的满足答案要求的串的个数是\(O(n)\)级别的,而且字符集也是\(O(n)\)级别的,所以我们考虑一下对于每个串的每一个点的任意一个字符的最近的上一次出现的位置。我们只考虑对于每个字符每个上一次出现的不同位置,就类似于线性筛一样的使得我们对于每个不同的可以记录答案的串只记录了一次。
这样回溯的实质其实就是在从字符串的后端往前端枚举出现哪个字符,由于每次合法的"枚举"一定可以对应上一个不同的可以计入答案的串,所以复杂度就是\(O(n)\)的,而不是\(O(26^{80})\)。
这样的手法应该有更普适的含义,在要输出所有合法方案而且保证所有合法方案的级别时,或许也可以用这个手法来解题。
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=81;
int data1[maxn],data2[maxn],sz1,sz2;
int dp[maxn][maxn];
int lastx[maxn][27];
int lasty[maxn][27];
char dfn[maxn];
typedef const int& ct;
set < string > s;
typedef set < string > :: iterator it;
inline void qr(int* p,int& cnt){
cnt=0;
register char c=getchar();
while(c<'a'||c>'z') c=getchar();
while(c>='a'&&c<='z') p[++cnt]=c-'a'+1,c=getchar();
}
void dfs(ct x,ct y,ct len){
if(!len){
s.insert(dfn);
return;
}
if(x<=0||y<=0)return;
for(register int t=1,t1,t2;t<=26;++t){
t1=lastx[x][t];
t2=lasty[y][t];
if(dp[t1][t2]==len){
dfn[len-1]=t+'a'-1;
dfs(t1-1,t2-1,len-1);
}
}
}
int main(){
qr(data1,sz1);
qr(data2,sz2);
for(register int t=1;t<=sz1;++t)
for(register int i=1;i<=sz2;++i){
if(data1[t]==data2[i])
dp[t][i]=dp[t-1][i-1]+1;
if(data1[t]!=data2[i])
dp[t][i]=max(dp[t-1][i],dp[t][i-1]);
}
for(register int t=1;t<=sz1;++t){
for(register int i=1;i<=26;++i)
lastx[t][i]=lastx[t-1][i];
lastx[t][data1[t]]=t;
}
for(register int t=1;t<=sz2;++t){
for(register int i=1;i<=26;++i)
lasty[t][i]=lasty[t-1][i];
lasty[t][data2[t]]=t;
}
dfs(sz1,sz2,dp[sz1][sz2]);
for(it t=s.begin();t!=s.end();++t)
cout<<*t<<'\n';
return 0;
}
【题解】POJ1934 Trip (DP+记录方案)的更多相关文章
- hdu1074 状态压缩dp+记录方案
题意: 给你一些作业,每个作业有自己的结束时间和花费时间,如果超过结束时间完成,一天扣一分,问你把n个作业完成最少的扣分,要求输出方案. 思路: 状态压缩dp,记录方案数的地方 ...
- PAT L3-001 凑零钱(01背包dp记录路径)
韩梅梅喜欢满宇宙到处逛街.现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债.韩梅梅手边有104枚来自各个星球的硬币,需要请你帮她盘算一下,是 ...
- 牛客网多校训练第三场 A - PACM Team(01背包变形 + 记录方案)
链接: https://www.nowcoder.com/acm/contest/141/A 题意: 有n(1≤n≤36)个物品,每个物品有四种代价pi,ai,ci,mi,价值为gi(0≤pi,ai, ...
- POJ 1952 BUY LOW, BUY LOWER DP记录数据
最长递减子序列.加记录有多少个最长递减子序列.然后须要去重. 最麻烦的就是去重了. 主要的思路就是:全面出现反复的值,然后还是同样长度的子序列.这里的DP记录的子序列是以当前值为结尾的时候,而且一定选 ...
- 【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)
ACM字符串 .长度不能超过n .字符串中仅包含大写字母 .生成的字符串必须包含字符串“ACM”,ACM字符串要求连在一块! ok,是不是很简单?现在告诉你n的值,你来告诉我这样的字符串有多少个 输入 ...
- poj1934 Trip【线性DP】【输出方案】
Trip Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3850 Accepted: 1030 Description ...
- CF10D-LCIS题解--线性DP+打印方案
题目链接: https://www.luogu.org/problemnew/show/CF10D 方法一 分析 \(LCS\)和\(LIS\)已经成烂大街的知识了,可是当这两个合并起来成为\(LCI ...
- $Poj1934\ Trip$ 线性$DP+$搜索
Luogu Description 爱丽丝和鲍伯想去度假,他们每个人都制定了一个参观城市的清单,该地区正好有26个城市,因此它们被编码为小写字母“a”到“z”.清单上可能重复出现某个城市.因为他们想一 ...
- POJ1934 Trip 题解
LCS 模板,但要输出具体方案,这就很毒瘤了. 神奇的预处理:fa[i][j]表示在 \(a\) 串的前 \(i\) 个字符中,字母表第 \(j\) 个字母最晚出现的位置,fb[i][j]同理. 这样 ...
随机推荐
- Spring Cloud学习总结(非原创)
文章大纲 一.课程内容总结二.课程学习地址三.学习资料下载四.参考文章 一.课程内容总结 二.课程学习地址 第一天:https://www.jianshu.com/p/a086421f4bfd第二 ...
- 2016北京集训测试赛(十四)Problem B: 股神小D
Solution 正解是一个\(\log\)的link-cut tree. 将一条边拆成两个事件, 按照事件排序, link-cut tree维护联通块大小即可. link-cut tree维护子树大 ...
- 如何使用Ext.create() 调用一个窗体
Ext.define("Scripts.Code.QM.OutgoingQuality.OQC.ReinspRequest.view.DefectContentsDetailInfoWind ...
- SELinux下更改mysql端口
默认情况下 mysql更改端口后是不能通过selinux的 提示启动错误,那么首先就要看mysql的错误日志 可是我不知道mysql错误日志的位置 首先,更改selinux的模式为passive 然后 ...
- mac与linux服务器之间使用ssh互通有无
1. 在mac上没有找到好用的shell图形界面的软件,但也是有办法的,使用ssh公钥达到互相有无目的 2.场景是mac连A(linux,以下简称A)服务器 3.登陆mac shell ,按comma ...
- ios编程规范
允许使用较长的描述尽量不要使用缩写,而是将完整的意思写出来.源于代码的维护可能会被不同文化背景的programmer阅读 适当的命名前缀,比如给变量,协议等,不要给方法加前缀 方法命名规则一般以小写字 ...
- HTML小技巧将table边框改为细线
HTML制作新手在用TABLE表格时,会碰到如何改变边线粗线,因为默认的TABLE边线设置即使是1px 是很粗的.因此会使用其他一些方法来制作出细线边框,这里介绍一种利用CSS来实现细线的方法,很有效 ...
- django中引入json
try: from django.utils import simplejson as jsonexcept: import simplejson as json
- C 标准库 - <assert.h>
C 标准库 - <assert.h> 简介 C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息. 已定义的宏 a ...
- 【oracle ocp知识点一】
1.怎样确定数据库是否启动 su - oracle ps -ef |grep ora_|head -2 两种关系数据库是ora或者是自己主动存储管理的asm开头的, 查看进程能够知道数据库实例至少已经 ...