Trip
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 3850   Accepted: 1030

Description

Alice and Bob want to go on holiday. Each of them has planned a route, which is a list of cities to be visited in a given order. A route may contain a city more than once. 
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

The input consists of two lines; the first line is Alice's list, the second line is Bob's list. 
Each list consists of 1 to 80 lower case letters with no spaces inbetween.

Output

The output should contain all routes that meet the conditions described above, but no route should be listed more than once. Each route should be printed on a separate line. There is at least one such non-empty route, but never more than 1000 different ones. Output them in ascending order.

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】【输出方案】的更多相关文章

  1. $Poj1934\ Trip$ 线性$DP+$搜索

    Luogu Description 爱丽丝和鲍伯想去度假,他们每个人都制定了一个参观城市的清单,该地区正好有26个城市,因此它们被编码为小写字母“a”到“z”.清单上可能重复出现某个城市.因为他们想一 ...

  2. 【题解】POJ1934 Trip (DP+记录方案)

    [题解]POJ1934 Trip (DP+记录方案) 题意: 传送门 刚开始我是这么设状态的(谁叫我DP没学好) \(dp(i,j)\)表示钦定选择\(i\)和\(j\)的LCS,然而你会发现这样钦定 ...

  3. 线性dp

    线性dp应该是dp中比较简单的一类,不过也有难的.(矩乘优化递推请出门右转) 线性dp一般是用前面的状态去推后面的,也有用后面往前面推的,这时候把循环顺序倒一倒就行了.如果有的题又要从前往后推又要从后 ...

  4. 线性DP之机器分配

    题目大意 自己瞅 (懒得打了) 思路 前面是很简单的线性dp,后面是模拟递归输出方案, 模拟递归可以设ny为机器数机器数,nx表示第nx个公司,tot为总盈利,那么则有\(a[nx][i]+dp[nx ...

  5. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  6. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

  7. 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门 ...

  8. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  9. POJ 2479-Maximum sum(线性dp)

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33918   Accepted: 10504 Des ...

  10. poj 1050 To the Max(线性dp)

    题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...

随机推荐

  1. vim markdown

    vim 安装vundle插件管理器 https://github.com/VundleVim/Vundle.vim Vundle for windows https://github.com/Vund ...

  2. matplotlib中的legend()——用于显示图例

    legend()的一个用法: 当我们有多个 axes时,我们如何把它们的图例放在一起呢?? 我们可以这么做: import matplotlib.pyplot as plt import numpy ...

  3. 利用PHPExcel导出Excel相关设置

    功能包括: 1.设置单元格格式,包括单元格边框.单元格高度.单元格宽度 2.合并指定的单元格 3.设置Excel数据源,并将数据源保护起来(这个是为了实现单元格下拉选项功能) 4.设置字体样式 pub ...

  4. poj 3740 Easy Finding(Dancing Links)

    Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15668   Accepted: 4163 Des ...

  5. CentOS 6.5配置SSH免密码登录

    centos 系统对权限的设置非常微妙,如果权限设置大了则ssh 拒绝,如果权限小了,则ssh 更是被拒绝(我曾经配置好久没有打通,就是因为权限过大的原因) 参考链接:http://www.linux ...

  6. 【Python】多线程2

    threading模块 import time import random import threading class Inclass: def __init__(self): print 'Inc ...

  7. 高级选项更改MathType数学公式样式

    MathType中系统的样式有很多种,我们将通过示例来演示如何更改样式定义达到修改等式的目的.使用样式将允许你迅速且方便的获得一种格式,这种格式将使你创建的等式具有统一的风格. 以下步骤中,我们将创建 ...

  8. HE算法与Scaler算法

    HE算法:图像直方图均衡化 Scaler算法:图像缩放 基于matab的scaler实现_图文_百度文库 https://wenku.baidu.com/view/016f5e4002768e9951 ...

  9. IDE、SATA、SCSI、SAS、FC、SSD 硬盘类型

    http://www.cnblogs.com/awpatp/archive/2013/01/29/2881431.html

  10. 单行dp复习hdu1087

    我写的想法是每个dp[i]都是前dp[i]的最大值 dp[i]就等于前全部dp[0...i-1]的最大值加上dp[i] 最大值是一个中间变量 最大值得选取条件就是序列的值大小都是递增的,也就是a[i] ...