zoukankan      html  css  js  c++  java
  • HDU 4681 String

    String

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 158    Accepted Submission(s): 69


    Problem Description
    Given 3 strings A, B, C, find the longest string D which satisfy the following rules:
    a) D is the subsequence of A
    b) D is the subsequence of B
    c) C is the substring of D
    Substring here means a consecutive subsequnce.
    You need to output the length of D.
     
    Input
    The first line of the input contains an integer T(T = 20) which means the number of test cases.
    For each test case, the first line only contains string A, the second line only contains string B, and the third only contains string C.
    The length of each string will not exceed 1000, and string C should always be the subsequence of string A and string B.
    All the letters in each string are in lowercase.
     
    Output
    For each test case, output Case #a: b. Here a means the number of case, and b means the length of D.
     
    Sample Input
    2 aaaaa aaaa aa abcdef acebdf cf
     
    Sample Output
    Case #1: 4 Case #2: 3
    Hint
    For test one, D is "aaaa", and for test two, D is "acf".
     
    Source
     
    Recommend
    zhuyuanchen520
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int N=1100;
    
    char a[N],b[N],c[N];
    int dp1[N][N],dp2[N][N],loc[N<<2][2],cnt;   //dp1[][]表示字符串a,b从前往后的最大公共子串,dp2[][]表示字符串a,b从后往前的最大公共子串
                            //loc[][]记录字符串c在a,b中出现的第一个位置和最后一个位置
    int len1,len2,len3;
    
    void solve(char *str,int len){  //求出loc[][]
        int i,j,k;
        for(i=1;i<=len;i++){
            if(str[i]==c[1]){
                for(j=i,k=1;j<=len && k<=len3;j++)
                    if(str[j]==c[k])
                        k++;
                if(k!=len3+1)
                    break;
                loc[cnt][0]=i;
                loc[cnt][1]=j-1;
                cnt++;
            }
        }
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        int t,cases=0;
        scanf("%d",&t);
        while(t--){
            scanf("%s%s%s",a+1,b+1,c+1);
            len1=strlen(a+1);
            len2=strlen(b+1);
            len3=strlen(c+1);
            memset(dp1,0,sizeof(dp1));
            for(int i=1;i<=len1;i++)
                for(int j=1;j<=len2;j++)
                    if(a[i]==b[j])
                        dp1[i][j]=dp1[i-1][j-1]+1;
                    else
                        dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]);
    
            memset(dp2,0,sizeof(dp2));
            for(int i=len1;i>=1;i--)
                for(int j=len2;j>=1;j--)
                    if(a[i]==b[j])
                        dp2[i][j]=dp2[i+1][j+1]+1;
                    else
                        dp2[i][j]=max(dp2[i+1][j],dp2[i][j+1]);
    
            cnt=0;
            solve(a,len1);
            int x=cnt;
            solve(b,len2);
            int y=cnt-x,ans=0;
            for(int i=0;i<x;i++)
                for(int j=0;j<y;j++)
                    ans=max(ans,dp1[loc[i][0]-1][loc[j+x][0]-1]+dp2[loc[i][1]+1][loc[j+x][1]+1]);
            printf("Case #%d: %d
    ",++cases,ans+len3);
        }
        return 0;
    }
  • 相关阅读:
    模拟出栈
    全排列 next_permutation 用法
    区间覆盖
    BFS GPLT L2-016 愿天下有情人都是失散多年的兄妹
    GPLT L2-014 列车调度
    图的联通分量个数统计(判断图是否联通)
    堆排序 GPLT L2-012 关于堆的判断
    牛客挑战赛 30 A 小G数数
    由树的中后序遍历求树的前层序遍历
    【HDOJ4699】Editor(对顶栈,模拟)
  • 原文地址:https://www.cnblogs.com/jackge/p/3260641.html
Copyright © 2011-2022 走看看