HDUOJ 4681 2013多校第8场第6题 String

来源:互联网 发布:美工专业就业前景 编辑:程序博客网 时间:2024/04/30 18:22

传送门

题意:略。

思路:找到a、b中所有的包含c序列的起点和终点位置,然后从中找出起点前和终点后的公共子序列的长度和c序列长度的和的最大值。

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int t;char a[1005],b[1005],c[1005];int la,lb,lc;int as[1005],ae[1005],bs[1005],be[1005],anum,bnum;int f[1005][1005],ff[1005][1005];void lcs(int s1,int e1,int s2,int e2){    memset(f,0,sizeof(f));    for(int i=s1;i<e1;i++)    {        for(int j=s2;j<e2;j++)        {            if(a[i]==b[j])            {                f[i+1][j+1]=f[i][j]+1;            }            else f[i+1][j+1]=max(f[i+1][j],f[i][j+1]);        }    }    memset(ff,0,sizeof(ff));    for(int i=e1-1;i>=s1;i--)    {        for(int j=e2-1;j>=s2;j--)        {            if(a[i]==b[j])            {                ff[i][j]=ff[i+1][j+1]+1;            }            else            {                ff[i][j]=max(ff[i+1][j],ff[i][j+1]);            }        }    }    //cout<<s1<<" "<<e1<<" "<<s2<<" "<<e2<<" "<<f[e1-1][e2-1]<<endl;    //return f[e1][e2];}int main(){    int ca=0;    scanf("%d",&t);    while(t--)    {        anum=bnum=0;        scanf("%s%s%s",a,b,c);        la=strlen(a);        lb=strlen(b);        lc=strlen(c);        for(int i=0;i<la;i++)        {            if(a[i]==c[0])            {                int num=1;                for(int j=i+1;j<la;j++)                {                    if(a[j]==c[num])                    {                        num++;                        if(num==lc)                        {                            as[anum]=i;                            ae[anum]=j;                            anum++;                            break;                        }                    }                }            }        }        for(int i=0;i<lb;i++)        {            if(b[i]==c[0])            {                int num=1;                for(int j=i+1;j<lb;j++)                {                    if(b[j]==c[num])                    {                        num++;                        if(num==lc)                        {                            bs[bnum]=i;                            be[bnum]=j;                            bnum++;                            break;                        }                    }                }            }        }        int ans=0;        lcs(0,la,0,lb);        for(int i=0;i<anum;i++)        {            for(int j=0;j<bnum;j++)            {                int ss=f[as[i]][bs[j]]+ff[ae[i]+1][be[j]+1]+lc;                if(ss>ans)ans=ss;            }        }        printf("Case #%d: %d\n",++ca,ans);    }    return 0;}


原创粉丝点击