hdu 4681(多校联赛8 最长公共子序列)

点击打开链接


题意:

给你三个字符串a,b,c,c是a和b的子序列,求d串的最大长度,d串满足:c是d的子串。


直接求c在a和b中出现的前后位置的最长公共子序列。

ab最大公共串+c串+ab最大公共串,这才是d的长度。。


#include"stdio.h"
#include"string.h"
#define N 1005
int dp1[N][N];
int dp2[N][N];
char a[N],b[N],c[N];
int l1,l2,l3,cnt;
struct node
{
	int l,r;
}A[N*100];
int max(int a,int b)
{
	return a>b?a:b;
}
void init()
{
	int i,j;
	l1=strlen(a+1);
	l2=strlen(b+1);
	l3=strlen(c+1);
	memset(dp1,0,sizeof(dp1));
	for(i=1;i<=l1;i++)
	{
		for(j=1;j<=l2;j++)
		{
			if(a[i]==b[j])
				dp1[i][j]=max(dp1[i-1][j-1]+1,max(dp1[i-1][j],dp1[i][j-1]));
			else dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]);
		}
	}
	memset(dp2,0,sizeof(dp2));
	for(i=l1;i>=1;i--)
	{
		for(j=l2;j>=1;j--)
		{
			if(a[i]==b[j])
				dp2[i][j]=max(dp2[i+1][j+1]+1,max(dp2[i+1][j],dp2[i][j+1]));
			else dp2[i][j]=max(dp2[i+1][j],dp2[i][j+1]);
		}
	}
}
void fun(char *s,char *ss,int l)
{
	int i,j;
	for(i=1;i<=l;i++)
	{
		if(s[i]==ss[1])
		{
			int k=1;
			for(j=i;j<=l;j++)
			{
				if(k<=l3&&s[j]==ss[k])k++;
				if(k>l3&&s[j]==ss[l3])
				{
					A[cnt].l=i;
					A[cnt++].r=j;break;
				}
			}
		}
	}	
}
int main()
{
	int T;
	int t=1;
	int i,j;
	scanf("%d",&T);
	getchar();
	while(T--)
	{
		gets(a+1);
		gets(b+1);
		gets(c+1);
		init();	
		cnt=0;
		fun(a,c,l1);
		int tt=cnt-1;
		fun(b,c,l2);
		int ans=0;
		for(i=0;i<=tt;i++)
		{
			for(j=tt+1;jans)ans=ttt;
			}
		}
		printf("Case #%d: %d\n",t++,ans+l3);
	}
	return 0;
}


你可能感兴趣的:(hdu 4681(多校联赛8 最长公共子序列))