Advanced Fruits
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1944   Accepted: 967   Special Judge

Description

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

Source

题意:

给你两个长度不超过100的字符串A,B。

要你找出一个最短的字符串C。

使得A,B都是C的子序列(不一定是子串).

思路:

開始看题目里面写的是sub-strings然后看例子百思不得其解。没办法。大胆如果出题人这两个概念分不清。思索片刻后想出了O(n^3)的算法。vis[k][i][j]表示C串长为k时包括了A串的前i-1个字符和B串的前j-1个位置。

那么

if(A[i]==B[j])

vis[k+1][i+1][j+1]=1;

else

vis[k+1][i+1][j]=1,vis[k+1][i][j+1]=1;

然后找到最小的k即可了。

比赛的时候各种犯傻。调试了非常久才调出来。

下来又想了下这道题。

认为先前的做法简直可爱到极致。为何生拉硬扯加个k.直接dp[i][j]表示包括了A串的前i-1个字符和B串的前j-1个位置的C串的最短长度。

if(A[i]==B[j])

dp[i][j]=dp[i-1][j-1]+1;

else

dp[i][j]=min(dp[i][j-1],dp[i-1][j])+1;

然后记录转移的方向就好了。

具体见代码:

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=100010;
int dp[150][150],path[150][150];
char sa[150],sb[150];
void print(int i,int j)
{
if(i==0&&j==0)
return;
if(path[i][j]==1)
{
print(i-1,j);
printf("%c",sa[i]);
}
else if(path[i][j]==-1)
{
print(i,j-1);
printf("%c",sb[j]);
}
else
{
print(i-1,j-1);
printf("%c",sa[i]);
}
}
int main()
{
int i,j,la,lb; while(~scanf("%s%s",sa+1,sb+1))
{
la=strlen(sa+1);
lb=strlen(sb+1);
for(i=1;i<=la;i++)
dp[i][0]=i,path[i][0]=1;
for(i=1;i<=lb;i++)
dp[0][i]=i,path[0][i]=-1;
for(i=1;i<=la;i++)
for(j=1;j<=lb;j++)
{
dp[i][j]=INF;
if(sa[i]==sb[j])//相等仅仅用添加一个字符
dp[i][j]=dp[i-1][j-1]+1,path[i][j]=0;
else
{
if(dp[i][j-1]<dp[i-1][j])//添加sb[j]
dp[i][j]=dp[i][j-1]+1,path[i][j]=-1;
else//添加sa[i]
dp[i][j]=dp[i-1][j]+1,path[i][j]=1;
}
}
print(la,lb);
printf("\n");
}
return 0;
}

比赛的做法:

#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int vis[210][150][150],path[210][150][150];
char sa[150],sb[150];
void print(int st,int i,int j)
{
//printf("st %d i %d j %d\n",st,i,j);
if(st==1)
{
if(path[st][i][j]==1)
printf("%c",sa[i-1]);
else if(path[st][i][j]==-1)
printf("%c",sb[j-1]);
else
printf("%c",sa[i-1]);
return;
}
if(path[st][i][j]==1)
{
print(st-1,i-1,j);
printf("%c",sa[i-1]);
}
else if(path[st][i][j]==-1)
{
print(st-1,i,j-1);
printf("%c",sb[j-1]);
}
else
{
print(st-1,i-1,j-1);
printf("%c",sa[i-1]);
}
}
int main()
{
int la,lb,i,j,k,len;
while(~scanf("%s%s",sa,sb))
{
la=strlen(sa);
lb=strlen(sb);
memset(vis,0,sizeof vis);
len=la+lb;
vis[1][1][0]=vis[1][0][1]=1,path[1][1][0]=1,path[1][0][1]=-1;
if (sa[0]==sb[0]) vis[1][1][1]=1,path[1][1][1]=0;
for(k=1;k<=len;k++)
{
if(vis[k][la][lb])
break;
//printf("k %d\n",k);
for(i=0;i<=la;i++)
for(j=0;j<=lb;j++)
{
if(!vis[k][i][j])
continue;
//printf("%d %d\n",i,j);
if(i<la&&j<lb&&sa[i]==sb[j]&&!vis[k+1][i+1][j+1])
vis[k+1][i+1][j+1]=1,path[k+1][i+1][j+1]=0;
else
{
if(!vis[k+1][i+1][j])
vis[k+1][i+1][j]=1,path[k+1][i+1][j]=1;
if(!vis[k+1][i][j+1])
vis[k+1][i][j+1]=1,path[k+1][i][j+1]=-1; }
}
}
//printf("k %d\n",k);
print(k,la,lb);
printf("\n");
}
return 0;
}

poj 2264 Advanced Fruits(DP)的更多相关文章

  1. LCS(打印全路径) POJ 2264 Advanced Fruits

    题目传送门 题意:两个字符串结合起来,公共的字符只输出一次 分析:LCS,记录每个字符的路径 代码: /* LCS(记录路径)模板题: 用递归打印路径:) */ #include <cstdio ...

  2. hdu 1503:Advanced Fruits(动态规划 DP & 最长公共子序列(LCS)问题升级版)

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  3. 最长公共子序列(加强版) Hdu 1503 Advanced Fruits

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  4. Advanced Fruits(HDU 1503 LCS变形)

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  5. Advanced Fruits(好题,LCS的模拟)

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  6. HDU-1053:Advanced Fruits(LCS+路径保存)

    链接:HDU-1053:Advanced Fruits 题意:将两个字符串合成一个串,不改变原串的相对顺序,可将相同字母合成一个,求合成后最短的字符串. 题解:LCS有三种状态转移方式,将每个点的状态 ...

  7. poj 2264(LCS)

    Advanced Fruits Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2158   Accepted: 1066   ...

  8. hdu 1503 Advanced Fruits(最长公共子序列)

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  9. hdu 1503 Advanced Fruits 最长公共子序列 *

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

随机推荐

  1. Flask+ Angularjs 实例: 创建博客

    允许任何用户注册 允许注册的用户登录 允许登录的用户创建博客 允许在首页展示博客 允许登录的用户退 后端 Flask-RESTful - Flask 的 RESTful 扩展 Flask-SQLAlc ...

  2. .NET重构(五):存储过程、触发器和函数的区别

    导读:在触发器的学习过程中,师傅讲了它的耦合性高,建议我能用存储过程,那到底什么是存储过程呢,自己也不是特别了解,还有就是,触发器也算是一种特殊的存储过程,为什么就不建议多用呢?接下来,就谈谈触发器. ...

  3. [luoguP2862] [USACO06JAN]把牛Corral the Cows(二分 + 乱搞)

    传送门 可以二分边长 然后另开两个数组,把x从小到大排序,把y从小到大排序 枚举x,可以得到正方形的长 枚举y,看看从这个y开始,往上能够到达多少个点,可以用类似队列来搞 其实发现算法的本质之后,x可 ...

  4. Bzoj1083 1083: [SCOI2005]繁忙的都市【MST】

    大水题,真不知道出题者是怎么把这么水的题出的这么长的TAT 其实这题在于考语文水平,一共三个要求,前两个要求意思就是要选出的道路是树形的,最后一个要求就是要权值最小,于是整个题意说白了就是求一棵MST ...

  5. 使用plantuml生成uml图

    主要包括以下三步: 一.到http://plantuml.com/download 下载plantuml.jar ,我将这个软件放置到home的/home/munication/WORKM/Progr ...

  6. unity的List构造函数在IOS平台存在缺陷

    当迩使用一个int[]或者string[]类似的数组时,以数组来初始化List对象,有可能在IOS平台上会出现初始化对象为空,比如 , }; List<int> listTest = ne ...

  7. Python入门--7--处理数据时学习到的东西

    一.数据导入(这里使用的是pands包) import pands as pd wenjian = pd.read_csv('路径') 二.数据变换 print wenjian.head()    # ...

  8. ZOJ 3717 二分+2-sat判定。

    好久没有2-sat了,此题当复习之用,二分求最大值+2-sat判断可行,此题主要跪于题意:The results should be rounded to three decimal places. ...

  9. delphi使用IdHTTP模拟提交页面方法总结

    http://blog.csdn.net/lxdcyh/article/details/3986800 1.拖入TIdHTTP控件,HandleRedirect设为True,否则可能会出现HTTP 3 ...

  10. 树莓派学习笔记——I2C设备载入和速率设置

    原文:http://blog.csdn.net/xukai871105/article/details/18234075 1.载入设备 方法1——临时载入设备 sudo modprobe -r i2c ...