最长公共子序列——输出

首先我不得不说这道题很傻逼....你要先求公共子序列的长度......然后去DFS一遍注意要倒着搜......公共子序列也要倒着找..........我做了好久,代码:

#include<bits/stdc++.h>
using namespace std;
char a[1001],b[1001];
int dp[1001][1001]={0};
int n1,n2,sum=0;
int ans[1001]={0};
int a1[1001][101],b1[1001][101];
int k=0;
bool pd=false;
void dfs(int ji_lu,int x,int y)
{
	if(pd==true) return ;//判断输出了吗
	if(ji_lu==0)//如果它的最长公共子序列的数为零
	{
		pd=true;
		for(int i=0;i<=k;i++)
		{
			cout<<char(ans[i]+65);//输出
		}
		return ;
	}
	for(int i=0;i<26;i++)//枚举26个字母
	{
		int a2=a1[x][i],b2=b1[y][i];
		if(dp[a2+1][b2+1]==ji_lu)//去找第一个相等的字母
		{
			ans[k++]=i;//记录
			dfs(ji_lu-1,a2-1,b2-1);//在搜一遍
			k--;//回溯
		}
	}
}
int main()
{
	cin>>a>>b;
	n1=strlen(a);
	n2=strlen(b);
	for(int i=0;i<n1/2;i++) swap(a[i],a[n1-i-1]);//将这个串倒过来
 	for(int i=0;i<n2/2;i++) swap(b[i],b[n2-i-1]);
	for(int i=1;i<=n1;i++)//最长公共子序列
	{
		for(int j=1;j<=n2;j++)
		{
			if(a[i-1]==b[j-1])
			{
				dp[i][j]=dp[i-1][j-1]+1;
			}
			else
			{
				dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
			}
		}
	}
	memset(a1,-1,sizeof(a1));
	memset(b1,-1,sizeof(b1));
	for(int i=0;i<n1;i++)
	{
		for(int j=i;j>=0;j--)
		{
			if(a1[i][a[j]-‘A‘]==-1)//找这个字母出现在第几个
			{
				a1[i][a[j]-‘A‘]=j;
			}
		}
	}
	for(int i=0;i<n2;i++)
	{
		for(int j=i;j>=0;j--)
		{
			if(b1[i][b[j]-‘A‘]==-1)
			{
				b1[i][b[j]-‘A‘]=j;
			}
		}
	}
	dfs(dp[n1][n2],n1-1,n2-1);//搜索
}

  出题人有病。

原文地址:https://www.cnblogs.com/dai-jia-ye/p/9359360.html

时间: 2024-07-30 23:45:03

最长公共子序列——输出的相关文章

51nod_1006 最长公共子序列,输出路径【DP】

题意: 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. 输出最长的子序列,如果有多个,随意输出1个. 思路: DP,同时DP记录路径. 代码: string a,b; int f[1005][1005]; int path[1005][1005]; void _print(int x,int y){ if(!x||!y) ret;

NYOJ 36 &amp;&amp;HDU 1159 最长公共子序列(经典)

链接:click here 题意:tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0<N<100)表示待测数据组数 接下来每组数据两行,分别为待测的两组字符串.每个字符串长度不大于1000. 输出 每组测试数据输出一个整数,表示最长公共子序列长度.每组

[BZOJ2423][HAOI2010]最长公共子序列

试题描述 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij = yj.例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列.对给定的两个字符序列,求出他们最长的公共子序列长度,以及最长公共子序列个数. 输入 第1行为第1个字

动态规划 - 最长公共子序列(LCS)

最长公共子序列也是动态规划中的一个经典问题. 有两个字符串 S1 和 S2,求一个最长公共子串,即求字符串 S3,它同时为 S1 和 S2 的子串,且要求它的长度最长,并确定这个长度.这个问题被我们称为 最长公共子序列问题. 与求最长递增子序列一样,我们首先将原问题分割成一些子问题,我们用 dp[i][j]表示 S1 中前 i 个字符与 S2 中前 j 个字符分别组成的两个前缀字符串的最 长公共子串长度. 显然的,当 i. j 较小时我们可以直接得出答案,如 dp[0][j]必 等于 0.那么,

第11章:最长公共子序列(LCS:Longest Common Subsequence)

方法:动态规划 <算法导论>P208 最优子结构 + 重叠子问题 设xi,yi,为前i个数(前缀) 设c[i,j]为xi,yi的LCS的长度 c[i,j] = 0 (i ==0 || j == 0) c[i,j] = a[i-1,j-1] + 1 (i,j>0 &&xi=yi) c[i,j] = max(c[i,j-1],c[i-1,j]) 求LCS(Xm-1 , Y)的长度与LCS(X , Yn-1)的长度,这两 个问题不是相互独立的:两者都需要求LCS(Xm-1,Yn

算法学习 - 最长公共子序列(LCS)C++实现

最长公共子序列 最长公共子序列的问题很简单,就是在两个字符串中找到最长的子序列,这里明确两个含义: 子串:表示连续的一串字符 . 子序列:表示不连续的一串字符. 所以这里要查找的是不连续的最长子序列, 动态规划 这里为什么要使用动态规划可以说一下,简单来说动态规划是为了降低时间复杂度的一种算法,申请一个额外空间,来保存每一个步骤的结果,最后从这些结果中找到最优的解. 这里有个问题就是:一般来说,当前的最优解,只与当前时刻和上一时刻有关系,和其他时刻没有关系,这样才能让动态规划发生作用,降低复杂度

hdu 1159 Common Subsequence(最长公共子序列 DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25416    Accepted Submission(s): 11276 Problem Description A subsequence of

算法重拾之路——最长公共子序列(LCS)

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第二章:动态规划 最长公共子序列 算法描述: 一个给定序列的子序列是该序列中删去若干元素后得到的序列.确切的说,若给定序列 X={ x1,x2,...,xm },则另一序列 Z = { z1,z2, ... ,zk },是X的子序列是指存在一个严格递增下标序列

求解两个序列的所有最长公共子序列(LCSes)

 摘要 本篇博文提供了实现求解所有最长公共子序列的程序实现,并提供输出所有公共子序列的方法解释,需要具备基础知识是求解一个公共子序列的动态规划方法,请自行查阅相关资料. 题目重述 子序列概念:设X=< x1, x2,┅, xm>,若有1≤i1< i2< ┅ <ik≤m,使得Z=< z1, z2,┅, zk> = < xi1, xi2,┅, xik>,则称Z是X的子序列,记为Z<X. 例如: X=<A,B,C,B,D,A,B>,