码迷,mamicode.com
首页 > 其他好文 > 详细

最长公共子序列——输出

时间:2018-07-24 14:04:27      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:swap   return   text   through   its   std   回溯   style   void   

首先我不得不说这道题很傻逼....你要先求公共子序列的长度......然后去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);//搜索 
}

  出题人有病。

最长公共子序列——输出

标签:swap   return   text   through   its   std   回溯   style   void   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!