hdu 4681(多校联赛8 最长公共子序列)

来源:互联网 发布:怎么做软件 编辑:程序博客网 时间:2024/05/14 07:55

点击打开链接


题意:

给你三个字符串a,b,c,c是a和b的子序列,求d串的最大长度,d串满足:c是d的子串。


直接求c在a和b中出现的前后位置的最长公共子序列。

ab最大公共串+c串+ab最大公共串,这才是d的长度。。


#include"stdio.h"#include"string.h"#define N 1005int dp1[N][N];int dp2[N][N];char a[N],b[N],c[N];int l1,l2,l3,cnt;struct node{int l,r;}A[N*100];int max(int a,int b){return a>b?a:b;}void init(){int i,j;l1=strlen(a+1);l2=strlen(b+1);l3=strlen(c+1);memset(dp1,0,sizeof(dp1));for(i=1;i<=l1;i++){for(j=1;j<=l2;j++){if(a[i]==b[j])dp1[i][j]=max(dp1[i-1][j-1]+1,max(dp1[i-1][j],dp1[i][j-1]));else dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]);}}memset(dp2,0,sizeof(dp2));for(i=l1;i>=1;i--){for(j=l2;j>=1;j--){if(a[i]==b[j])dp2[i][j]=max(dp2[i+1][j+1]+1,max(dp2[i+1][j],dp2[i][j+1]));else dp2[i][j]=max(dp2[i+1][j],dp2[i][j+1]);}}}void fun(char *s,char *ss,int l){int i,j;for(i=1;i<=l;i++){if(s[i]==ss[1]){int k=1;for(j=i;j<=l;j++){if(k<=l3&&s[j]==ss[k])k++;if(k>l3&&s[j]==ss[l3]){A[cnt].l=i;A[cnt++].r=j;break;}}}}}int main(){int T;int t=1;int i,j;scanf("%d",&T);getchar();while(T--){gets(a+1);gets(b+1);gets(c+1);init();cnt=0;fun(a,c,l1);int tt=cnt-1;fun(b,c,l2);int ans=0;for(i=0;i<=tt;i++){for(j=tt+1;j<cnt;j++){int ttt;ttt=dp1[A[i].l-1][A[j].l-1]+dp2[A[i].r+1][A[j].r+1];if(ttt>ans)ans=ttt;}}printf("Case #%d: %d\n",t++,ans+l3);}return 0;}