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

传送门

题意:略。

思路:找到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;
}


你可能感兴趣的:(多校,Baoge,hduoj)