输出最长公共子序列

来源:互联网 发布:java 两种状态的按钮 编辑:程序博客网 时间:2024/05/17 01:05

试题描述
还是公共子序列,如果不知道什么叫公共子序列,请先阅读第0071题。本题给定两个字符串 str1 和 str2 ,请编写程序求出这两个字符串最长的公共子串。如果最大长度的公共子串有多个,输出字典序最小的那一个。
输入
两行,每行一个只含英文字母的字符串
输出
一个字符串
输入示例
ABCDDDBAMN BCDABM
输出示例
BCDAM
其他说明
输入的字符串长度均不会超过1000。

#include<cstdio>#include<cctype>#include<algorithm>#include<cstring>#define maxn 1005using namespace std;inline int read(){    int x=0,f=1;char c=getchar();    for(;!isdigit(c);c=getchar()) if(c=='-')f=-1;    for(;isdigit(c);c=getchar()) x=x*10+c-'0';    return x*f;}int lasta[maxn][27],lastb[maxn][27]; int f[maxn][maxn],ans[maxn],cnt;char a[maxn],b[maxn];bool flag;void dfs(int res,int n,int m){ if(flag) return; if(res==0)    { flag=1; for(int i=0;i<cnt;i++) printf("%c",ans[i]+'A'); printf("\n"); return; } for(int i=0;i<26;i++) { int posa=lasta[n][i],posb=lastb[m][i]; if(f[posa+1][posb+1]==res) { ans[cnt++]=i; dfs(res-1,posa-1,posb-1); cnt--; } }}int main(){    scanf("%s%s",a,b);    int n=strlen(a),m=strlen(b);    for(int i=0;i<n/2;i++)swap(a[i],a[n-i-1]); for(int i=0;i<m/2;i++)swap(b[i],b[m-i-1]);  for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i-1]==b[j-1]) f[i][j]=f[i-1][j-1]+1; else f[i][j]=max(f[i-1][j],f[i][j-1]); memset(lasta,-1,sizeof(lasta)); memset(lastb,-1,sizeof(lastb)); for(int i=0;i<n;i++) { for(int j=i;j>=0;j--)if(lasta[i][a[j]-'A']==-1) lasta[i][a[j]-'A']=j; }    for(int i=0;i<m;i++) { for(int j=i;j>=0;j--)if(lastb[i][b[j]-'A']==-1) lastb[i][b[j]-'A']=j; } dfs(f[n][m],n-1,m-1);    return 0;}

几句废话
这玩意挺难得,我想了好久

原创粉丝点击