poj 2264 Advanced Fruits(DP)
|
Advanced Fruits
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 Sample Output appleach 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)的更多相关文章
- LCS(打印全路径) POJ 2264 Advanced Fruits
题目传送门 题意:两个字符串结合起来,公共的字符只输出一次 分析:LCS,记录每个字符的路径 代码: /* LCS(记录路径)模板题: 用递归打印路径:) */ #include <cstdio ...
- hdu 1503:Advanced Fruits(动态规划 DP & 最长公共子序列(LCS)问题升级版)
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- 最长公共子序列(加强版) Hdu 1503 Advanced Fruits
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- Advanced Fruits(HDU 1503 LCS变形)
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- Advanced Fruits(好题,LCS的模拟)
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- HDU-1053:Advanced Fruits(LCS+路径保存)
链接:HDU-1053:Advanced Fruits 题意:将两个字符串合成一个串,不改变原串的相对顺序,可将相同字母合成一个,求合成后最短的字符串. 题解:LCS有三种状态转移方式,将每个点的状态 ...
- poj 2264(LCS)
Advanced Fruits Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2158 Accepted: 1066 ...
- hdu 1503 Advanced Fruits(最长公共子序列)
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- hdu 1503 Advanced Fruits 最长公共子序列 *
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
随机推荐
- Leetcode 402.移掉k位数字
移调k位数字 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : ...
- 九度oj 题目1017:还是畅通工程
题目描述: 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可 ...
- 【Luogu】P3847调整队形(DP)
题目链接 DP果真是考思维啊 增加一个数的操作等价于删掉那个不和谐的数的操作. 所以1.2操作可以忽略. 剩下3.4操作,则可以设计f[i][j]是将区间[i,j]变成回文序列需要的操作数. if(a ...
- 刷题总结——切蛋糕(ssoj)
题目: 切蛋糕 (cake.cpp/c/pas) [问题描述] BG 有一块细长的蛋糕,长度为�. 有一些人要来BG 家里吃蛋糕, BG把蛋糕切成了若干块(整数长度),然后分给这些人.为了公平,每个人 ...
- 升级完Android Studio3.2后,打包release出现的错误
升级完Android Studio2.3后,打包release出现的错误 Error:Execution failed for task ':qq:lintVitalRelease'.> Lin ...
- poj 3083 dfs,bfs
传送门 Children of the Candy Corn Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I6 ...
- 有关 GCC 及 JNA 涉及动态库/共享库时处理库文件名的问题
动态库尤其是共享库在 Linux 环境下普遍存在库文件名包含版本号的情况,比如 Linux 环境下经常会发现一个共享库的真实文件名是 libfoo.so.1.1.0,而同时会有多个指向该真实库文件的软 ...
- delphi使用IdHTTP模拟提交页面方法总结
http://blog.csdn.net/lxdcyh/article/details/3986800 1.拖入TIdHTTP控件,HandleRedirect设为True,否则可能会出现HTTP 3 ...
- vue之组件理解(一)
组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data.computed.watch.methods 以及生命周期钩子等.仅有的例外是像 el 这样根实例特有的选项. ...
- BZOJ——1571: [Usaco2009 Open]滑雪课Ski
http://www.lydsy.com/JudgeOnline/problem.php?id=1571 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: ...