您的位置:首页 > 其它

hdu 4681 String (动态规划-最长公共子序列)

2013-08-15 19:07 369 查看
1、http://acm.hdu.edu.cn/showproblem.php?pid=4681

2、题目大意

给定3个字符串a,b,c,求一个字符串d,使得d是a.b 的子序列(在ab中不一定是连续的),c是d的子字符串(c是连续的),首先找出ab字符串对应的d的区间,然后枚举区间,求前后两端的最长公共子序列,代码超时了。。。

看了网上的代码,终于知道为什么错了,dp[][]可以预处理,没必要每次都调用DP()

3、题目

String

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)

Total Submission(s): 153 Accepted Submission(s): 67



[align=left]Problem Description[/align]
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.

[align=left]Input[/align]
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.

[align=left]Output[/align]
For each test case, output Case #a: b. Here a means the number of case, and b means the length of D.

[align=left]Sample Input[/align]

2
aaaaa
aaaa
aa
abcdef
acebdf
cf


[align=left]Sample Output[/align]

Case #1: 4
Case #2: 3


4、AC代码:‘

#include<stdio.h>
#include<algorithm>
using namespace std;
#include<string.h>
#define N 1005
char a
;
char b
;
char c
;
int tsa
;
int tea
;
int tsb
;
int teb
;

struct node
{
int s;
int e;
} ansa
,ansb
;
int dp1

,dp2

;
int la,lb,lc;
char transa
,transb
;
void DP()
{
memset(dp1,0,sizeof(dp1));
for(int i=1; i<=la; i++)
{
for(int j=1; j<=lb; j++)
{
if(a[i-1]==b[j-1])
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));
int j=0;
for(int i=la-1;i>=0;i--)
transa[j++]=a[i];
j=0;
for(int i=lb-1;i>=0;i--)
transb[j++]=b[i];
for(int i=1; i<=la; i++)
{
//printf("aa.e=%d %d\n",aa.e,la);
for(int j=1; j<=lb; j++)
{
if(transa[i-1]==transb[j-1])
dp2[i][j]=dp2[i-1][j-1]+1;
else
dp2[i][j]=max(dp2[i-1][j],dp2[i][j-1]);
}
}
}
int main()
{

int t,cas=0;
scanf("%d",&t);
while(t--)
{
cas++;
int maxx=-999999;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%s%s%s",a,b,c);
lc=strlen(c);
la=strlen(a);
lb=strlen(b);
int ta=0,tb=0,k;
for(int i=0;i<la;i++)
{
if(a[i]==c[0])
{
k=1;
int flag=0;
for(int j=i+1;j<la;j++)
{
if(a[j]==c[k])
k++;
if(k==lc)
{
flag=j;
break;
}
}
if(flag!=0)
{
ansa[ta].s=i;
ansa[ta++].e=flag;
}
}
}
for(int i=0;i<lb;i++)
{
if(b[i]==c[0])
{
k=1;
int flag=0;
for(int j=i+1;j<lb;j++)
{
if(b[j]==c[k])
k++;
if(k==lc)
{
flag=j;
break;
}
}
if(flag!=0)
{
ansb[tb].s=i;
ansb[tb++].e=flag;
}
}
}
DP();
for(int i=0; i<ta; i++)
{
for(int j=0; j<tb; j++)
{
//printf("**%d %d %d %d\n",ansa[i].s,ansa[i].e,ansb[j].s,ansb[j].e);
//DP(ansa[i],ansb[j]);
maxx=max(maxx,dp1[ansa[i].s][ansb[j].s]+dp2[la-1-ansa[i].e][lb-1-ansb[j].e]);
}
}
printf("Case #%d: %d\n",cas,maxx+lc);
}
return 0;
}


4、超时的代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
#include<string.h>
#define N 1005
char a
;
char b
;
char c
;
int tsa
;
int tea
;
int tsb
;
int teb
;

struct node
{
int s;
int e;
} ansa
,ansb
;
int dp

;
int la,lb,lc;
int maxx=-99999;
void DP(node aa,node bb)
{
int l=max(aa.s,bb.s);
int tp1=0,tp2=0;
memset(dp,0,sizeof(dp));
for(int i=1; i<=aa.s; i++)
{
for(int j=1; j<=bb.s; j++)
{
if(a[i-1]==b[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
tp1=dp[aa.s][bb.s];
// printf("tp1=%d\n",tp1);
l=max((la-aa.e),(lb-bb.e));
memset(dp,0,sizeof(dp));

for(int i=aa.e+1; i<la; i++)
{
//printf("aa.e=%d %d\n",aa.e,la);
for(int j=bb.e+1; j<lb; j++)
{
if(a[i]==b[j])
dp[i-aa.e][j-bb.e]=dp[i-1-aa.e][j-1-bb.e]+1;
else
dp[i-aa.e][j-bb.e]=max(dp[i-1-aa.e][j-bb.e],dp[i-aa.e][j-1-bb.e]);
}
}
tp2=dp[la-aa.e][lb-bb.e];
//printf("tp2=%d\n",tp2);
if(tp1+tp2>maxx)
maxx=tp1+tp2;
}
int finda(int s,int e)
{
int j=0;
for(int i=s; i<=e; i++)
{
if(a[i]==c[j])
j++;
}
if(j==lc)
return 1;
return 0;
}
int findb(int s,int e)
{
int j=0;
for(int i=s; i<=e; i++)
{
if(b[i]==c[j])
j++;
}
if(j==lc)
return 1;
return 0;
}
int main()
{

int t,cas=0;
scanf("%d",&t);
while(t--)
{
cas++;
maxx=-999999;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%s%s%s",a,b,c);
lc=strlen(c);
la=strlen(a);
lb=strlen(b);
char tmp1=c[0];
char tmp2=c[lc-1];
int sa=0,ea=0;
int maxl=max(la,lb);
int sb=0,eb=0;
for(int i=0; i<maxl; i++)
{
if(a[i]==tmp1)
tsa[sa++]=i;
if(a[i]==tmp2)
tea[ea++]=i;
if(b[i]==tmp1)
tsb[sb++]=i;
if(b[i]==tmp2)
teb[eb++]=i;
}

int k=0;
for(int i=0; i<sa; i++)
{
for(int j=0; j<ea; j++)
{
if(finda(tsa[i],tea[j]))
{
ansa[k].s=tsa[i];
ansa[k].e=tea[j];
k++;
}
}
}
int l=0;
for(int i=0; i<sb; i++)
{
for(int j=0; j<eb; j++)
{
if(findb(tsb[i],teb[j]))
{
ansb[l].s=tsb[i];
ansb[l].e=teb[j];
l++;
}
}
}
for(int i=0; i<k; i++)
{
for(int j=0; j<l; j++)
{
//printf("**%d %d %d %d\n",ansa[i].s,ansa[i].e,ansb[j].s,ansb[j].e);
DP(ansa[i],ansb[j]);
}
}
printf("Case #%d: %d\n",cas,maxx+lc);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: