hdu-4681-String

题意:

给你字符串A,B,C,让你找一个字符串D,使得D串是A,B的字串,C串是D的连续字串。

做法:

找出C串在A,B串的位置。

对于每一个位置对,D串的长度为前一半的最长公共子序列+C串的长度+后一半的最长公共子序列

程序:

#include<iostream>
#include<stdio.h>
#include<vector>
#include<string.h>
using namespace std;
char sta[1001];
char stb[1001];
char stc[1001];
int lena,lenb,lenc;
int dp[1001][1001];
int dpf[1001][1001];
struct list
{
    int x;
    int y;
}node,n1,n2;
vector<list>vec[5];
void dps()
{
    int i,j;
    for(i=0;i<lena;i++)
        if(sta[i]==stb[0])
            for(i;i<lena;i++)dp[i][0]=1;
    for(i=0;i<lenb;i++)
        if(sta[0]==stb[i])
            for(i;i<lenb;i++)dp[0][i]=1;
    for(i=1;i<lena;i++)
    {
        for(j=1;j<lenb;j++)
        {
            if(sta[i]==stb[j])dp[i][j]=dp[i-1][j-1]+1;
            else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }
}
void dpfs()
{
    int i,j;
    for(i=lena-1;i>=0;i--)
        if(sta[i]==stb[lenb-1])
            for(i;i>=0;i--)dpf[i][lenb-1]=1;
    for(i=lenb-1;i>=0;i--)
        if(sta[lena-1]==stb[i])
            for(i;i>=0;i--)dpf[lena-1][i]=1;
    for(i=lena-2;i>=0;i--)
    {
        for(j=lenb-2;j>=0;j--)
        {
            if(sta[i]==stb[j])dpf[i][j]=dpf[i+1][j+1]+1;
            else dpf[i][j]=max(dpf[i+1][j],dpf[i][j+1]);
        }
    }
}
void init()
{
    memset(dp,0,sizeof(dp));
    memset(dpf,0,sizeof(dpf));
    vec[0].clear();
    vec[1].clear();
    gets(sta);
    gets(stb);
    gets(stc);
    lena=strlen(sta);
    lenb=strlen(stb);
    lenc=strlen(stc);
}
void sear(char str[],int pos)
{
    int lens=strlen(str);
    int i,j,k;
    for(i=0;i<lens;i++)
    {
        if(str[i]==stc[0])
        {
            for(k=0,j=i;j<lens;j++)
            {
                if(str[j]==stc[k])k++;
                if(k==lenc)break;
            }
            if(j<lens)
            {
                node.x=i;
                node.y=j;
                vec[pos].push_back(node);
              //  cout<<pos<<" "<<i<<" "<<j<<endl;
            }
        }
    }
}
void prin(int cas)
{
    int l1=vec[0].size();
    int l2=vec[1].size();
    int maxx=0;
    int i,j;
    for(i=0;i<l1;i++)
    {
        for(j=0;j<l2;j++)
        {
            n1=vec[0][i];
            n2=vec[1][j];
            int c1,c2;
            c1=c2=0;
            if(n1.x-1>=0&&n2.x-1>=0)c1=dp[n1.x-1][n2.x-1];
            if(n1.y+1<lena&&n2.y+1<lenb)c2=dpf[n1.y+1][n2.y+1];
            maxx=max(maxx,c1+c2+lenc);
          //  printf("%d,%d--%d,%d--%d--%d\n",n1.x,n1.y,n2.x,n2.y,c1,c2);
        }
    }
    printf("Case #%d: %d\n",cas,maxx);
}
int main()
{
    int T,t;
    //freopen("data.in","r",stdin);
    scanf("%d%*c",&T);
    for(t=1;t<=T;t++)
    {
        init();
        dps();
        dpfs();
        sear(sta,0);
        sear(stb,1);
        prin(t);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值