51nod 1006 最长公共子序列Lcs【DP】

匿名 (未验证) 提交于 2019-12-02 23:34:01

1006 最长公共子序列Lcs


1 秒 / 131,072 KB / 基础题

问题

给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
比如两个串为:
abcicba
abdkscab
ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。

输入

第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)

输出

输出最长的子序列,如果有多个,随意输出1个。

输入样例

abcicba
abdkscab

输出样例

abca

题目。

解题时卡在没有想到好的方法输出路径(我用DFS一直错)。办法:记录路径。

如何记录路径:记录此状态的上一步,或者说记录当前是如何由上一步得出的。即:方向。

#include<cstdio> #include<string> #include<iostream>  using namespace std;  string a,b,ans; const int Max_num=1e3+17; int dp[Max_num][Max_num],book[Max_num][Max_num];	//book[][]记录方向  int main(){ 	cin>>a>>b; 	int la=a.length(),lb=b.length(),tail=0; 	for(int i=0;i<=la;++i) for(int j=0;j<lb;++j) dp[i][j]=0; 	for(int i=1;i<=la;++i){ 		for(int j=1;j<=lb;++j){ 			if(a[i-1]==b[j-1]){		//分三个方向 				dp[i][j]=dp[i-1][j-1]+1; 				book[i][j]=0; 			}  			else if(dp[i-1][j]>dp[i][j-1]){	 				dp[i][j]=dp[i-1][j]; 				book[i][j]=1; 			} 			else{ 				dp[i][j]=dp[i][j-1]; 				book[i][j]=2; 			}  		}  	} 	bool flag=false; 	for(int i=la;i>0;){ 	for(int j=lb;j>0;){ 		if(book[i][j]==0){ 			ans=a[i-1]+ans; 			if(j-1>0&&i-1>0) j-=1,i-=1; 			else{ flag=true;break;} 		} 		else if(book[i][j]==1){ 			if(i-1>0) --i; 			else{ flag=true;break;} 		} 		else{ 			if(j-1>0)--j; 			else{ flag=true;break;} 		}  	} 	if(flag)break; 	} 	 	/*for(int i=0;i<=la;++i){ 		for(int j=0;j<=lb;++j) 		printf("%d ",dp[i][j]); 		printf("\n"); 	} 	printf("\n"); 	for(int i=0;i<=la;++i){ 		for(int j=0;j<=lb;++j) 		printf("%d ",book[i][j]); 		printf("\n"); 	}*/ 	cout<<ans<<endl; 	return	0; }  
文章来源: https://blog.csdn.net/qq_43482299/article/details/90047125
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!