2013多校聯合8 String (hdu 4681)

http://acm.hdu.edu.cn/showproblem.php?pid=4681


String

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


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.
 


算是本次比賽的簽到題吧。

首先枚舉C 在A 和B 的起始位置,要使A 和B 的公共子序列儘量大,那麼C 在A 和B 的佔用長度肯定越少越好。所以就分成兩個問題:
1. 對A,B 的任意起始位置,求出最近的包含C 的結束位置。先記錄一個數組A[i][j](0 i < lenA; 0 j < 26) 保存在i 位置後跟i 最近的字符j 的距離。這個數組可以O(N2) 暴力枚舉出來。然後對於每個起始位置i,按C從左往右尋找距離當前位置最近的相應字符即可。


2. 對於任意A,B 的起始位置,求出A,B 在起始位置之前的最長公共子序列,用同樣的方法求出與起始位置相應的結束位置以後的最長公共子序列。只需定義dp[i][j] 代表A 的i 位置下B 的j 位置下的最長公共子序列長度。複雜度爲O(lenA lenB)。上面兩個問題都預處理後每次查詢爲O(1)。所以總複雜度爲O(N2).


#include <iostream>
#include <stdio.h>
#include <string.h>
#define ll long long
#define maxn 1010
using namespace std;
int dp[maxn][maxn][2];
int po[2][maxn];
char A[maxn],B[maxn],C[maxn];
void init(int la,int lb)
{
       int i,j;
       for(i=0;i<=la+1;i++)
       {
           for(j=0;j<=lb+1;j++)
           dp[i][j][0]=dp[i][j][1]=0;
           po[0][i]=0;
       }
       for(i=0;i<=lb+1;i++)
       po[1][i]=0;
}
int main()
{
   // freopen("dd.txt","r",stdin);
   int ncase,T=0;
   scanf("%d",&ncase);
   while(ncase--)
   {
       printf("Case #%d: ",++T);
       scanf("%s%s%s",A+1,B+1,C+1);
       int la=strlen(A+1),lb=strlen(B+1),lc=strlen(C+1);
       int i,j;
       init(la,lb);
       for(i=1;i<=la;i++)
       {
           for(j=1;j<=lb;j++)
           {
               if(A[i]==B[j])
               dp[i][j][0]=max(dp[i-1][j-1][0]+1,max(dp[i][j-1][0],dp[i-1][j][0]));
               else
               {
                   dp[i][j][0]=max(dp[i][j-1][0],dp[i-1][j][0]);
               }
           }
       }
       for(i=la;i>=1;i--)
       {
           for(j=lb;j>=1;j--)
           {
               if(A[i]==B[j])
               dp[i][j][1]=max(dp[i+1][j+1][1]+1,max(dp[i][j+1][1],dp[i+1][j][1]));
               else
               {
                   dp[i][j][1]=max(dp[i][j+1][1],dp[i+1][j][1]);
               }
           }
       }
       for(i=1;i<=la;i++)
       {
           if(A[i]!=C[1])
           continue;
           if(lc==1)
           {
               po[0][i]=i;
               continue;
           }
           int num=2,tru=0;
           for(int j=i+1;j<=la;j++)
           {
               if(A[j]==C[num])
               {
                   num++;
               }
               if(num>lc)
               {
                   po[0][i]=j;
                   tru=1;
                   break;
               }

           }
           if(!tru)
           break;
       }
       for(i=1;i<=lb;i++)
       {
           if(B[i]!=C[1])
           continue;
           if(lc==1)
           {
               po[1][i]=i;
               continue;
           }
           int num=2,tru=0;
           for(int j=i+1;j<=lb;j++)
           {
               if(B[j]==C[num])
               {
                   num++;
               }
               if(num>lc)
               {
                   po[1][i]=j;
                   tru=1;
                   break;
               }

           }
           if(!tru)
           break;
       }
       int ans=0;
       for(i=1;i<=la;i++)
       {
           if(po[0][i]!=0)
           {
               for(j=1;j<=lb;j++)
               {
                   if(po[1][j]!=0)
                   {

                       int ii=po[0][i],jj=po[1][j];
                       ans=max(ans,dp[i-1][j-1][0]+dp[ii+1][jj+1][1]);
                   }
               }
           }
       }
       printf("%d\n",ans+lc);
   }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章