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问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...
随机推荐
- Android Activity 传递数据
activity中数据的传递方式有2中,一种是使用putExtra()传递,另外一种是传递Bundle对象,使用putExtras()方法. 方法一 发送数据 putExtra()传送的是键值对,第一 ...
- Hello World! 这是我的第一个 CGI 程序
Hello World! 这是我的第一个 CGI 程序上面的 C++ 程序是一个简单的程序,把它的输出写在 STDOUT 文件上,即显示在屏幕上.在这里,值得注意一点,第一行输出 Content-ty ...
- C++字符串转化为数字的库函数
原文链接:http://blog.csdn.net/tsinfeng/article/details/5844838 1.atoi 功 能:把一字符串转换为整数 用 法:int atoi(const ...
- 【Java面试题】37 说出ArrayList,Vector, LinkedList的存储性能和特性
ArrayList和Vector都是使用数组方式存储数据,此 数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插 ...
- Post方式调用wcf服务
我们平常在PC端调用WCF服务,只要知道WCF服务的地址,客户端直接添加引用服务就可以使用了,殊不知还有其他方式,其实,我们也可以 通过HTTP POST的方式调用WCF服务,这样就不用添加引用了,在 ...
- QlikView报表显示连续若干个月内活跃用户的数量
之前有朋友提到了这样一个需求,要计算三年中每年都有销售记录的客户量,仅仅有近期两年有销售纪录的客户量(假如某个用户2012年和2014年都有记录,在2013年没有则不计算在内).以及近期一年的新增客户 ...
- day17<集合框架+>
集合框架(HashSet存储字符串并遍历) 集合框架(HashSet存储自定义对象保证元素唯一性) 集合框架(HashSet存储自定义对象保证元素唯一性图解及代码优化) 集合框架(HashSet如何保 ...
- org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Can
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Can ...
- vue 组件库
iView https://www.iviewui.com/ Radon UI https://luojilab.github.io/radon-ui/#!/ Element http://eleme ...
- (DCloud)用这个来写H5,好像好厉害的样子哦
HBuilder: http://www.dcloud.io MUI: http://dev.dcloud.net.cn/mui/getting-started/ http://dev.dcloud. ...