HDU1503-Advanced Fruits(LCS)

The company “21st Century Fruits” has specialized in creating new sorts of fruits by transferring genes from one fruit into the genome of another one. Most times this method doesn’t work, but sometimes, in very rare cases, a new fruit emerges that tastes like a mixture between both of them.
A big topic of discussion inside the company is “How should the new creations be called?” A mixture between an apple and a pear could be called an apple-pear, of course, but this doesn’t sound very interesting. The boss finally decides to use the shortest string that contains both names of the original fruits as sub-strings as the new name. For instance, “applear” contains “apple” and “pear” (APPLEar and apPlEAR), and there is no shorter string that has the same property.

A combination of a cranberry and a boysenberry would therefore be called a “boysecranberry” or a “craboysenberry”, for example.

Your job is to write a program that computes such a shortest name for a combination of two given fruits. Your algorithm should be efficient, otherwise it is unlikely that it will execute in the alloted time for long fruit names.
Input
Each line of the input contains two strings that represent the names of the fruits that should be combined. All names have a maximum length of 100 and only consist of alphabetic characters.

Input is terminated by end of file.
Output
For each test case, output the shortest name of the resulting fruit on one line. If more than one shortest name is possible, any one is acceptable.
Sample Input
apple peach
ananas banana
pear peach
Sample Output
appleach
bananas
pearch

分析:

题意:
给你两个字符串,要你用这两个字符串组成一个新的字符串,在组成的字
符串中字符在原串中的相对顺序不变的情况,并且可以在组成的字符串中找到原先两个字符串,要求这个组成的字符串中字母数最少,并输出这个字符串。

解析:
我们可以将两个字符串的公共部分从一个字串中抽掉,然后在顺序不变情况下合并两个字串,从这个合并的字符串中按顺序取出一部分字符可以组成任意一个字串。

定义两个字符串:str1和str2,定义一个dp数组,dp[i][j]表示以str1[i]结尾和以str2[j]结尾的字符串的最大公共子串的长度。

因为要求合并的字符串要最短,所以我们要来去掉最长的公共子列们(因为公共子列有很多个,有的字符中较前面的短的公共子列可能和会与另外一个子串的较后面的字符串有更长的公共子列),所以我逆序合并!

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 105

using namespace std;

int dp[N][N];

int main()
{
	string str1,str2,last;
	while(cin>>str1>>str2)
	{
		int len1=str1.length();
		int len2=str2.length();
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=len1;i++)
		{
			for(int j=1;j<=len2;j++)
			{
				if(str1[i-1]==str2[j-1])
					dp[i][j]=dp[i-1][j-1]+1;
				else
					dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
			}
		}
		if(!dp[len1][len2])
		{
			cout<<str1<<str2<<endl;
			continue;
		}
		last.clear();
		while(len1>0&&len2>0)
		{
			if(dp[len1][len2]==dp[len1-1][len2-1]+1&&str1[len1-1]==str2[len2-1])
			{
				last+=str1[len1-1];
				len1--;
				len2--;
			}
			else
			{
				if(dp[len1-1][len2]>dp[len1][len2-1])
				{
					last+=str1[len1-1];
					len1--;
				}
				else
				{
					last+=str2[len2-1];
					len2--;
				}
			}
		}
		while(len2>0)
		{
			last+=str2[len2-1];
			len2--;
		}
		while(len1>0)
		{
			last+=str1[len1-1];
			len1--;
		}
		for(int i=last.length();i>0;i--)
		{
			cout<<last[i-1];
		}
		cout<<endl;
	}
	return 0;
}
发布了64 篇原创文章 · 获赞 17 · 访问量 865

猜你喜欢

转载自blog.csdn.net/weixin_43357583/article/details/105692580
LCS
今日推荐