最长公共子序列hdu1503
Posted 6262369sss
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长公共子序列hdu1503相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1503
题意:给你两个字符串,把这两个字符串合并,使合并之后的字符串最短,并且合并之后的字符之间的相对位置和在原字符串中的相对位置相同,其实意思就是叫我们求最长公共子序列,主要是输出的顺序,一开始不知道要保持相对位置不变,后面百度了才知道。
具体思路就是dp+DFS,dp是计算最长公共子序列的长度和求最长公共子序列时走过的路径,DFS是用来输出答案并保持相对位置不变。
具体看代码:
#include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<map> #include<stack> #include<cmath> #include<vector> #include<set> #include<cstdio> #include<string> #include<deque> using namespace std; typedef long long LL; #define eps 1e-8 #define INF 0x3f3f3f3f #define maxn 1005 /*struct point{ int u,w; }; bool operator <(const point &s1,const point &s2) { if(s1.w!=s2.w) return s1.w>s2.w; else return s1.u>s2.u; }*/ int dp[105][105]; int n,m,k,t; char str1[105],str2[105]; int path[105][105];//记录在求LCS时的路径 void DFS(int a,int b) { if(a==-1&&b==-1)//终止条件 return; if(path[a+1][b+1]==1) { DFS(a-1,b-1);//往对角线方向走 cout<<str1[a]; } else if(path[a+1][b+1]==2) { DFS(a,b-1);//往左走 cout<<str2[b]; } else { DFS(a-1,b);//往上 cout<<str1[a]; } } int main() { while(scanf("%s %s",str1,str2)!=EOF) { int len1=strlen(str1); int len2=strlen(str2); memset(dp,0,sizeof(dp)); for(int i=0;i<=len1;i++) path[i][0]=3;//往上走,直到开头 for(int i=0;i<=len2;i++) path[0][i]=2;//往左走 for(int i=0;i<len1;i++){//因为字符串从0开始,但是dp下标是从1开始,所以dp下标加1 for(int j=0;j<len2;j++){ if(str1[i]==str2[j]) { dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+1); path[i+1][j+1]=1;//往对角线方向 } else if(dp[i+1][j]>dp[i][j+1]) { dp[i+1][j+1]=dp[i+1][j]; path[i+1][j+1]=2;//往左走 } else { dp[i+1][j+1]=dp[i][j+1]; path[i+1][j+1]=3;//往上走 } } } DFS(len1-1,len2-1);//输出答案,从两个字符串的结尾DFS printf(" "); } return 0; }
以上是关于最长公共子序列hdu1503的主要内容,如果未能解决你的问题,请参考以下文章
HDU 6774 String Distance(最长公共子序列 LCS)
hdu 1159 Common Subsequence(dp 最长公共子序列问题LCS)