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. PHP 获取文件名和扩展名的方法

    dirname(path) path: 代表你的文件路径,必须为绝对路径,可以使用__FILE__, 表示列出当前文件的绝对路径,包含文件名 函数会返回当前文件的上一级路径,也就是除了文件名称的路径 ...

  2. x86保护模式 控制寄存器和系统地址寄存器

    控制寄存器和系统地址寄存器 控制寄存器    crx cr0   指示cpu工作方式的控制位  包含启用和禁止分页管理机制的控制位  包含控制浮点协处理器操作的控制位   注意必须为0的位 cr2和c ...

  3. TOJ 4815: 关押罪犯

    4815: 关押罪犯 Time Limit(Common/Java):10004MS/12000MS     Memory Limit:65536KByte Total Submit: 2       ...

  4. 【UML】9种图+包图

    导读:在UML的学习中,介绍了9种图,外加一个包图.这9种图和4大关系,可以说是UML的一个核心内容.我根据自己的笔记,以及查阅的一些资料,对这9种图和包图,做一个总结. 一.基本定义 1.1  总体 ...

  5. 九度oj 题目1208:10进制 VS 2进制

    题目描述: 对于一个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们乘B为A的二进制逆序数.    例如对于十进制数173,它的二进制形式为10101101,逆序排列得到10 ...

  6. BZOJ 3990 [SDOI2015]排序 ——搜索

    [题目分析] 可以发现,操作的先后顺序是不影响结果的,那么答案就是n!的和. 可以从小的步骤开始搜索,使得每一个当前最小的块都是上升的数列,然后看看是否可行即可. 复杂度好像是4^n [代码](哪里写 ...

  7. SPOJ 4060 A game with probability

    博弈论+dp+概率 提交链接- 题意不是很好懂 Ai 表示剩 i 个石头. A 先手的获胜概率. Bi 表示剩 i 个石头. B先手的获胜概率. 如果想选,对于 Ai: 有 p 的概率进入 Bi−1 ...

  8. Java 模板权重随机

    Template templates=...// 所有的模板 final int _weights=1000; // 所有的模板权重 Template _template=null; //随机一个权重 ...

  9. msp430入门学习41

    msp430的其他九 msp430入门学习

  10. 学习linux之 rwx对于目录和档案的意义(节选自鸟哥)

    權限對檔案的重要性 檔案是實際含有資料的地方,包括一般文字檔.資料庫內容檔.二進位可執行檔(binary program)等等. 因此,權限對於檔案來說,他的意義是這樣的: r (read):可讀取此 ...