给出两个序列,要求合并后的序列的子序列包含所给序列,为合并后序列的最短长度和有几种合并方式可以合并出最短序列。类似于求公共子序列的方法,具体转移方程见代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=35; int l[maxn][maxn],d[maxn][maxn]; char s1[maxn],s2[maxn]; int main(){ int t,tt=0;scanf("%d%*c",&t); while(t--){ memset(l,0,sizeof(l)); memset(d,0,sizeof(d)); for(int i=0;i<maxn;++i){ l[i][0]=l[0][i]=i; d[i][0]=d[0][i]=1; } gets(s1+1); gets(s2+1); int l1=(int)strlen(s1+1),l2=(int)strlen(s2+1); for(int i=1;i<=l1;++i){ for(int j=1;j<=l2;++j){ if(s1[i]==s2[j]){ l[i][j]=l[i-1][j-1]+1; d[i][j]=d[i-1][j-1]; } else{ if(l[i-1][j]>l[i][j-1]){ l[i][j]=l[i][j-1]+1; d[i][j]=d[i][j-1]; } else if(l[i-1][j]<l[i][j-1]){ l[i][j]=l[i-1][j]+1; d[i][j]=d[i-1][j]; } else{ l[i][j]=l[i][j-1]+1; d[i][j]=d[i-1][j]+d[i][j-1]; } } } } printf("Case #%d: %d %d\n",++tt,l[l1][l2],d[l1][l2]); } return 0; }
|
** 本文迁移自我的CSDN博客,格式可能有所偏差。 **