题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1503
题意:给出两个字符串 要求输出包含两个字符串的所有字母的最短序列。注意输出的顺序不能变。//意会一下吧,我说不清=.=
思路:最长公共子序列的变形,需要记录位置。直接看代码应该就可以懂,不是很难。
click here:http://www.cnblogs.com/a-clown/p/5918080.html //hdu1159 最长公共子序列裸题。
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; #define ll long long struct node { int x,y; ///x,y代表公共子串中的字母分别在两个子串中的位置 char ch; ///分别记录两个位置和字母 } ans[205]; char a[105],b[105]; int dp[105][105]; char c[210]; int main() { while(cin>>a>>b) { int len1=strlen(a); int len2=strlen(b); memset(dp,0,sizeof(dp)); for(int i=1; i<=len1; i++) for(int j=1; j<=len2; 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]); if(dp[len1][len2]==0) { cout<<a<<b<<endl; continue; } int p=len1-1,q=len2-1,k=0; while(p>=0 && q>=0) ///注意逆序更好写 { if(dp[p+1][q+1]==dp[p][q]+1 && a[p]==b[q]) { ans[k].x=p; ans[k].y=q; ans[k++].ch=a[p]; p--; q--; } else if(dp[p][q+1]>dp[p+1][q]) p--; else q--; } int x=0,y=0; for(int i=k-1; i>=0; i--) { while(x!=ans[i].x) cout<<a[x],x++; while(y!=ans[i].y) cout<<b[y],y++; cout<<ans[i].ch; x++; y++; } cout<<a+ans[0].x+1<<b+ans[0].y+1<<endl; } return 0; }