String
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1250 Accepted Submission(s): 455
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.
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.
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: 3HintFor test one, D is "aaaa", and for test two, D is "acf".
Source
题意:
给定A、B、C三个串。求一个最长的串D。使得D是A,B串的公共子串(不要求连续),且使C为D的连续子串。
解题突破口:c串连续
思路:
满足条件的D串的形式为 x+c+z ;x为c前面的A、B最大连续子串,y为c后面的A、B最大连续子串,那么先预处理dp1[i][j] - A的i位置前面、B的j位置前面最长子序列,dp2[i][j] - A的i位置后面、B的j位置后面最长子序列,然后枚举c的首字母在A、B中的位置,预处理好c在此位置时分别延续到A、B最后面的位置,那么就可以O(1)更新ans了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 1005
#define MAXN 100005
#define mod 1000000007
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;
int n,m,ans;
int len1,len2,len3;
char a[maxn],b[maxn],c[maxn];
int dp1[maxn][maxn],dp2[maxn][maxn];
int last1[maxn],last2[maxn];
vector<int>v1,v2;
void presolve()
{
int i,j,t;
len1=strlen(a+1);
len2=strlen(b+1);
len3=strlen(c+1);
memset(last1,0,sizeof(last1));
memset(last2,0,sizeof(last2));
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
v1.clear();
for(i=1; i<=len1; i++)
{
if(a[i]==c[1])
{
v1.push_back(i);
t=2;
if(len3==1)
{
last1[i]=i;
continue ;
}
for(j=i+1; j<=len1; j++)
{
if(a[j]==c[t])
{
t++;
if(t>len3)
{
last1[i]=j;
break ;
}
}
}
}
}
v2.clear();
for(i=1; i<=len2; i++)
{
if(b[i]==c[1])
{
v2.push_back(i);
t=2;
if(len3==1)
{
last2[i]=i;
continue ;
}
for(j=i+1; j<=len2; j++)
{
if(b[j]==c[t])
{
t++;
if(t>len3)
{
last2[i]=j;
break ;
}
}
}
}
}
for(i=1; i<=len1; i++)
{
for(j=1; j<=len2; j++)
{
if(a[i]==b[j]) dp1[i][j]=max(dp1[i][j],dp1[i-1][j-1]+1);
else dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]);
}
}
for(i=len1; i>=1; i--)
{
for(j=len2; j>=1; j--)
{
if(a[i]==b[j]) dp2[i][j]=max(dp2[i][j],dp2[i+1][j+1]+1);
else dp2[i][j]=max(dp2[i][j+1],dp2[i+1][j]);
}
}
}
void solve()
{
int i,j,t,u,v;
ans=0;
for(i=0; i<v1.size(); i++)
{
for(j=0; j<v2.size(); j++)
{
u=v1[i];
v=v2[j];
if(last1[u]&&last2[v])
{
ans=max(ans,dp1[u-1][v-1]+dp2[last1[u]+1][last2[v]+1]+len3);
}
}
}
}
int main()
{
int i,j,t,test=0;
scanf("%d",&t);
for(i=1; i<=t; i++)
{
scanf("%s%s%s",a+1,b+1,c+1);
presolve();
solve();
printf("Case #%d: %d\n",++test,ans);
}
return 0;
}
/*
2
acdbb
acdb
acd
cxxyxxjz
xyz
xz
*/