【题解】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]同理. 这样 ...
随机推荐
- Java中final和static关键字总结
1.final: final关键字可用于类.方法.变量前. final修饰的类不可被继承,例如java.lang.Math就是一个 final类,不可被继承. final修饰变量,在显示初始化后不可改 ...
- Css 基础学习
css 基本选择器 css基本选择器有三种方法 第一种: class选择器 .c1{ color: red;} <div class='c1'>hello world</div> ...
- TIDB 安装
https://my.oschina.net/dmdgeeker/blog/718564 SQL 层一直是用 Golang 在开发,存储引擎 TiKV 用的 Rust
- Storage protocol stacks
http://brasstacksblog.typepad.com/brass-tacks/ http://brasstacksblog.typepad.com/brass-tacks/2016/02 ...
- C语言实现的水仙花数
#include <stdio.h>void main(){ int ge,shi,bai; for (int i =100; i < 1000; i++) { ...
- php开发中sql语句拼接示例
1.插入语句 $sql="insert into Ad(AdClassID,AdType,AdTit,AdFileName,AdUrl,AShow,Addtime) values('&quo ...
- 转: 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
from: https://github.com/RubyLouvre/agate/issues/8 今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以 ...
- linux中kill几个有用信号
kill用法 kill -signal PID 15 (SIGTERM) 正常方式杀死进程:(这种方式可能会存在一些问题:进程的子进程可能会无法终止,并继续系统资源) PID 或者 kill PID ...
- AngularJS中,<span class="bluetext" ng-bind="ctrl.user.name|uppercase"></span>和{{ctrl.user.name|uppercase}}是等价的,但不等于<span class="bluetext" ng-bind="ctrl.user.name|uppercase"/>
代码下载:https://files.cnblogs.com/files/xiandedanteng/angularjsAttenSpan.rar AngularJS中,<span class= ...
- [Redis]windows下redis的安装和启动
官方的下载地址是: http://redis.io/download 在win64一栏中能够看到redis原本是没有windows版本号的,windows版本号是Microsoft Open Tech ...