poj1934 Trip【线性DP】【输出方案】
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 3850 | Accepted: 1030 |
Description
As they want to travel together, they have to agree on a common route. None wants to change the order of the cities on his or her route or add other cities. Therefore they have no choice but to remove some cities from the route. Of course the common route should be as long as possible.
There are exactly 26 cities in the region. Therefore they are encoded on the lists as lower case letters from 'a' to 'z'.
Input
Each list consists of 1 to 80 lower case letters with no spaces inbetween.
Output
Sample Input
abcabcaa
acbacba
Sample Output
ababa
abaca
abcba
acaba
acaca
acbaa
acbca
Source
题意:
求最长公共子序列,要求输出所有方案。
思路:
最长公共子序列好求,难点在输出方案。
用dp[i][j]表示处理到alice[i]和bob[j]时的最优解。如果alice[i]bob[j]不相等,dp[i][j]从dp[i-1][j], dp[j][i-1]中取较大的。相等,则dp[i-1][j-1]+1
先得到最优解,然后我们来输出所有方案。排序和去重都简单,用个set就行了。
首先我们预处理出alice串1~i的子串中,字符j+'a'最后一次出现的位置,存入pos1[i][j]。对bob串也做同样的处理。
然后我们进行递归。len1表示alice子串长度,len2表示bob子串长度,len表示公共串的子串长度。
枚举26个字母,找到他们在子串中最后出现的位置,如果我们发现dp[p1][p2] = len,那么说明这是一种可行的方案。并且这表示,这个字母会出现在这个方案的len位置。于是我们继续递归,去找(len1-1,len2-1,len-1)。直到len小于0了,说明现在当前跑出来的这个串跑完了,他是一个完整的方案,insert进set。如果在len到0之前,len1或者len2就已经小于0了,说明这个方案最后不可行了,也就不会insert,而会回溯。整个过程相当于是一个dfs。
WA了一次是因为输出了一下方案数的个数.....
//#include <bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<vector>
#include<map>
#include<set> #define inf 0x3f3f3f3f
using namespace std;
typedef long long LL; char alice[], bob[], tmp[];
int dp[][], pos1[][], pos2[][];
set<string> ans;
int lena, lenb; void solve(int len1, int len2, int len)
{
if(len <= ){
string str;
str = tmp + ;
//memset(tmp, 0, sizeof(tmp));
//cout<<str<<endl;
ans.insert(str);
return;
}
if(len1 > && len2 > ){
for(int i = ; i < ; i++){
int p1 = pos1[len1][i];
int p2 = pos2[len2][i];
if(dp[p1][p2] == len){
tmp[len] = i + 'a';
solve(p1 - , p2 - , len - );
}
}
} } int main()
{
while(scanf("%s%s", alice + , bob + ) != EOF){
lena = strlen(alice + );
lenb = strlen(bob + );
//ans.clear(); for(int i = ; i <= lena; i++){
dp[i][] = ;
}
for(int j = ; j <= lenb; j++){
dp[][j] = ;
} int tmpi = -, tmpj = -;
for(int i = ; i <= lena; i++){
for(int j = ; j <= lenb; j++){
dp[i][j] = max(dp[i][j], dp[i - ][j]);
dp[i][j] = max(dp[i][j], dp[i][j - ]);
if(alice[i] == bob[j]){
dp[i][j] = dp[i - ][j - ] + ;
}
}
} memset(pos1, -, sizeof(pos1));
memset(pos2, -, sizeof(pos2));
for(int i = ; i <= lena; i++){
for(int j = ; j < ; j++){
if(alice[i] == j +'a'){
pos1[i][j] = i;
}
else{
pos1[i][j] = pos1[i - ][j];
}
}
}
for(int i = ; i <= lenb; i++){
for(int j = ; j < ; j++){
if(bob[i] == j + 'a'){
pos2[i][j] = i;
}
else{
pos2[i][j] = pos2[i - ][j];
}
}
} //printf("%d\n", dp[lena][lenb]);
memset(tmp, , sizeof(tmp));
solve(lena, lenb, dp[lena][lenb]);
set<string>::iterator iter;
for(iter = ans.begin(); iter != ans.end(); iter++){
cout<<*iter<<endl;
} } return ;
}
poj1934 Trip【线性DP】【输出方案】的更多相关文章
- $Poj1934\ Trip$ 线性$DP+$搜索
Luogu Description 爱丽丝和鲍伯想去度假,他们每个人都制定了一个参观城市的清单,该地区正好有26个城市,因此它们被编码为小写字母“a”到“z”.清单上可能重复出现某个城市.因为他们想一 ...
- 【题解】POJ1934 Trip (DP+记录方案)
[题解]POJ1934 Trip (DP+记录方案) 题意: 传送门 刚开始我是这么设状态的(谁叫我DP没学好) \(dp(i,j)\)表示钦定选择\(i\)和\(j\)的LCS,然而你会发现这样钦定 ...
- 线性dp
线性dp应该是dp中比较简单的一类,不过也有难的.(矩乘优化递推请出门右转) 线性dp一般是用前面的状态去推后面的,也有用后面往前面推的,这时候把循环顺序倒一倒就行了.如果有的题又要从前往后推又要从后 ...
- 线性DP之机器分配
题目大意 自己瞅 (懒得打了) 思路 前面是很简单的线性dp,后面是模拟递归输出方案, 模拟递归可以设ny为机器数机器数,nx表示第nx个公司,tot为总盈利,那么则有\(a[nx][i]+dp[nx ...
- LightOJ1044 Palindrome Partitioning(区间DP+线性DP)
问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...
- Codeforces 176B (线性DP+字符串)
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...
- hdu1712 线性dp
//Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...
- POJ 2479-Maximum sum(线性dp)
Maximum sum Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33918 Accepted: 10504 Des ...
- poj 1050 To the Max(线性dp)
题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...
随机推荐
- linux -- ubuntu 脚本开机自启动
有一个脚本想在ubuntu 虚拟机开机时,自动运行. 创建脚本文件 在“/opt/lampp/”下新建一个脚本文件:lampp_start.sh #!/bin/bash /opt/lampp/lamp ...
- 在Terminal中的光标的使用技巧
如何简单操作? 在 Terminal(终端) 中,有许多操作技巧,这里就介绍几个简单的. 光标 up(方向键上) 可以调出输入历史执行记录,快速执行命令 down(方向键下) 配合 up 选择历史执行 ...
- 【matlab】error:试图访问 im2(1,1211);由于 size(im2)=[675,1210],索引超出范围。
试图访问 im2(1,1211):由于 size(im2)=[675,1210],索引超出范围. 出错 dect (line 14) if abs((im2(i,j))-(im1(i,j)))> ...
- Ocx控件注册不成功?可能是tlb文件导致~
Ocx文件是最常用的文件,实际操作中常常需要注册之~ 但是问题来了,经常会出现注册不成功的问题: 解决方法: 1.以“管理员身份”注册 2.Dependency Walker查看依赖是否缺失 3.查看 ...
- mybatis由浅入深day01_4.7根据用户名称模糊查询用户信息_4.8添加用户((非)自增主键返回)
4.7 根据用户名称模糊查询用户信息 4.7.1 映射文件 使用User.xml,添加根据用户名称模糊查询用户信息的sql语句. 4.7.2 程序代码 控制台: 4.8 添加用户 4.8.1 映射文件 ...
- Java精选笔记_EL表达式
EL表达式 初始EL EL是一种可以简化JSP页面的表达式,EL表达式的语法非常简单都是以"${"符号开始,以"}"符号结束的 EL表达式是一种简单的数据&qu ...
- Java精选笔记_集合【List(列表)接口】
List(列表)接口 简介 List接口继承自Collection接口,是单列集合的一个重要分支,习惯性地会将实现了List接口的对象称为List集合. 元素是有序的,即元素的存入顺序和取出顺序一致, ...
- Effective C++ Item 15 Provide access to raw resources in resource-managing classes
In last two item, I talk about resource-managing using RAII, now comes to the practical part. Often, ...
- ios button标记
在写项目的时候,for循环创建多个button,在需要设置背景图片和,需要标记所选中的button的需求, 在这里提供两种方法: 一: 1:把for循环创建的button全部装到一个新建的数组中,把他 ...
- php-fpm打开错误日志的配置
nginx与apache不一样,在apache中可以直接指定php的错误日志,那样在php执行中的错误信息就直接输入到php的错误日志中,可以方便查询. 在nginx中事情就变成了这样:nginx只对 ...