题意翻译

【题目描述】

输入两个A~Z组成的字符串(长度均不超过30),找一个最短的串,使得输入的两个串均是它的子序列(不一定连续出现)。你的程序还应统计长度最短的串的个数。

e.g.:ABAAXGF和AABXFGA的最优解之一为AABAAXGFGA,一共有9个解。

【输入格式】

有多组数据。第一行一个整数T表示数据组数。接下来的2T行,每行一个字符串,含义如题所示。

【输出格式】

共T行。第i行格式为

Case #i: x y

其中x为最短串的长度,y为最优解的个数。

题目描述

PDF

解析:

作为一名生物渣渣,蒟蒻再次感到了多方面综合发展的必要性。。。。

最近老做最短路,今天我们就来做一道很水(nan)的动态规划~

下面我们进入正题,这个题的本质是求:最短公共超序列的长度和个数;

所谓的最短公共超序列,其实可以这样通俗地理解:找到一个最短的串,让给定的两个串都是这个新串的子序列。

这个题和最短公共超序列板子的唯一的不同就是需要统计超序列的个数。

于是我们可以先跑一边最短公共超序列。

设dp[i][j]表示a串前i个字符,b串前j个字符所构成的最短公共超序列长度。

在真正进行dp之前,首先初始化dp数组。

for(int i=1;i<=100;i++)dp[i][0]=dp[0][i]=i;

然后我们来想状态转移方程。

当a[i]==b[j]时,最短公共超序列最后一位是确定的,它的长度一定是这两个串之前的超序列长度+1,其中的1表示这个字符本身。

当他们不同时,去选择之前状态中最短的一个,实际上是对应超序列中最后一位a[i]还是b[j]。

于是完整的状态转移方程不难写出:

 if(a[i-]==b[j-])dp[i][j]=dp[i-][j-]+;//a[i],b[j]减1是因为循环变量是从1循环到<=len;
else dp[i][j]=min(dp[i-][j]+,dp[i][j-]+);

跑完了最短公共超序列,我们就可以开始统计它的个数。

设f[i][j]表示a串前i个字符,b串前j个字符所构成的最短公共超序列个数。

同样,在正式统计之前,先进行初始化。

for(int i=;i<=;i++)f[i][]=f[][i]=;

然后我们开始统计。

当a[i]==b[j]的时候,序列的末尾是确定的,只有一种可能性。所以f[i][j]=f[i-1][j-1];

当a[i]!=b[j]的时候,哪个超序列更短取哪个。

最后就是当他们的超序列不同但是长度相同时,两个都可以取,加起来就好。

完整的统计过程:

 if(a[i-]==b[j-])f[i][j]=f[i-][j-];
else if(dp[i-][j]<dp[i][j-])f[i][j]=f[i-][j];
else if(dp[i-][j]>dp[i][j-])f[i][j]=f[i][j-];
else f[i][j]=f[i-][j]+f[i][j-];

最后上AC代码:

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
string a,b;
int dp[][],f[][],t;
int main()
{
cin>>t;
getchar();
for(int k=;k<=t;k++)
{
memset(dp,,sizeof(dp));
memset(f,,sizeof(f));
getline(cin,a);
getline(cin,b);
int len1=a.size(),len2=b.size();
for(int i=;i<=;i++)dp[i][]=dp[][i]=i;
for(int i=;i<=len1;i++)
{
for(int j=;j<=len2;j++)
{
if(a[i-]==b[j-])dp[i][j]=dp[i-][j-]+;
else dp[i][j]=min(dp[i-][j]+,dp[i][j-]+);
}
}
for(int i=;i<=;i++)f[i][]=f[][i]=;
for(int i=;i<=len1;i++)
{
for(int j=;j<=len2;j++)
{
if(a[i-]==b[j-])f[i][j]=f[i-][j-];
else if(dp[i-][j]<dp[i][j-])f[i][j]=f[i-][j];
else if(dp[i-][j]>dp[i][j-])f[i][j]=f[i][j-];
else f[i][j]=f[i-][j]+f[i][j-];
}
}
printf("Case #%d: %d %d\n",k,dp[len1][len2],f[len1][len2]);
}
return ;
}

到此为止,这个题已经讲解完了,接下来是笔者跟这道题的渊源。

我最开始接触OI是在半年前,也许有人会惊讶我半年就学到了SCS这种比较难一些的算法,我之所以学的比同年纪的人快,

很大程度上是和这道题有关系的。

我第一次看到这道题,是4个月前,是因为同社团的人为了出风头,在网上随便找了篇题解贴到了我们OJ上,结果测评过了,

当然,这位同学之后被老师发现了,于是就被骂了一顿。。。。

当时我就想,如果我能凭我的能力做出来这道题,该多么的好,于是我就开始奋斗,

不夸张地说,真是“夜以继日”地学;

在同社团的人也算是比较优秀了,到了更高一级的班学习。

当然,我也觉得信息学十分有乐趣,学到现在,我也不光只是想做出来这道“电子人的基因”了,还有更多,更富有挑战性,更有趣的题等着我去做。

但我可以说,如果没有这道题给我的激励作用,我不可能学的比现在更好。真要说起来,我还得感谢那位抄代码的同学。

终于, 2019-04-22 20:58:55;我做出了这道日思夜想的“电子人的基因”。

这就是一道“电子人的基因”的力量。

UVA10723 电子人的基因 Cyborg Genes的更多相关文章

  1. UVA10723 电子人的基因

    UVA10723 电子人的基因 题目比较难找附上链接:https://vjudge.net/problem/UVA-10723 题目描述: 给你两个字符串,你需要找出一个最短的字符串,使得两个给定字符 ...

  2. UVa 10723 电子人的基因(LCS)

    https://vjudge.net/problem/UVA-10723 题意: 输入两个A~Z组成的字符串,找一个最短的串,使得输入的两个串均是它的子序列,另外还需要统计长度最短的串的个数. 思路: ...

  3. 10723 Cyborg Genes (LCS + 记忆化搜索)

    Problem F Cyborg Genes Time Limit 1 Second September 11, 2132. This is the day that marks the beginn ...

  4. UVa 10723 LCS变形 Cyborg Genes

    题解转自: UVA 10723 Cyborg Genes - Staginner - 博客园 首先这个题目肯定是按最长公共子序列的形式进行dp的,因为只有保证消去的一部分是最长公共子序列才能保证最后生 ...

  5. UVa10723 - Cyborg Genes

    这题我能想到的解决方法是: 最优解的长度好找,两串的长度和-LCS: 根据anslen,枚举出解的数目...但想不出简单有效的枚举方法,这种做法可能超时 网上看大神的博客后,发现大家都用的此方法: 最 ...

  6. uva 10723 Cyborg Genes(LCS变形)

    题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=107450#problem/C 题意:输入两个字符串,找一个最短的串,使得输入的两个 ...

  7. Cyborg Genes

    题意: 给两个字符串,求最短的以两字符串为子序列的字符串和个数 分析: 最长公共子序列的变形,num[i][j]表示个数 #include <map> #include <set&g ...

  8. UVA-10273 Cyborg Genes (DP)

    题目大意:给两个字符串a.b,找出一个最短的字符串c,使得这两个字符串都是c的子序列.只需找出p的最小长度和最小长度时的个数. 题目分析:与LCS问题类似.最小长度的状态转移方程,dp(i,j)=mi ...

  9. UVa 10723 Cyborg Genes (LCS, DP)

    题意:给定两行字符串,让你找出一个最短的序列,使得这两个字符串是它的子串,并且求出有多少种. 析:这个题和LCS很像,我们就可以利用这个思想,首先是求最短的长度,不就是两个字符串长度之和再减去公共的么 ...

随机推荐

  1. centos6.5安装nginx+python+uwsgi+django

    nginx+uwsgi+django环境部署及测试 默认系统自带的python2.6.6 第一步(安装setuptools) wget https://pypi.python.org/packages ...

  2. 程序一 用记事本建立文件src.dat,其中存放若干字符。编写程序,从文件src.dat中读取数据,统计其中的大写字母、小写字母、数字、其它字符的个数,并将这些数据写入到文件test.dat中。

    用记事本建立文件src.dat,其中存放若干字符.编写程序,从文件src.dat中读取数据,统计其中的大写字母.小写字母.数字.其它字符的个数,并将这些数据写入到文件test.dat中. #inclu ...

  3. XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Khamovniki

    A. Ability Draft 记忆化搜索. #include<stdio.h> #include<iostream> #include<string.h> #i ...

  4. scrapy模拟登录

    对于scrapy来说,也是有两个方法模拟登陆: 直接携带cookie 找到发送post请求的url地址,带上信息,发送请求 scrapy模拟登陆之携带cookie 应用场景: cookie过期时间很长 ...

  5. jdk1.8的环境下打包成jdk1.6

    第一步: 选中项目 ------->properties 第二部:(修改java build path和java conpiler) 第三部:需要打包成jdk6的jar包,就改成jre6. 注意 ...

  6. 使用Dubbo的SPI扩展机制实现自定义LoadBalance——方法一 修改Dubbo源代码

    一. 拉取源码 到Dubbo官网 https://github.com/apache/incubator-dubbo/tree/2.5.x 下载源码,解压. 二. 导入IDEA 选择解压后的源码目录, ...

  7. linux_grub resue模式恢复

    //20190417 今天中午装linux的电脑崩了…… 一开始还以为是什么硬件问题,搞了半天,是更新的时候吧grub启动项弄坏了 行吧,没人教咱就上网搜,搞一下午搞出来了 ============= ...

  8. OO第二次博客作业--第二单元总结

    第一次作业 1. 设计策略 第一次作业,一共三个线程,主线程.输入线程和电梯线程,有一个共享对象--调度器(队列). 调度的策略大多集中到了电梯里,调度器反而只剩下一个队列. 2. 基于度量的分析 类 ...

  9. [dev][go] 入门Golang都需要了解什么

    一 什么是Golang 首先要了解Golang是什么. Golang是一门计算机编程语言:可以编译成机器码的像python一样支持各种特性的高级语言. 由Google发明,发明人之一是K,就是C语言的 ...

  10. [math] 什么是双曲函数(转发)

    我完全不记得上高中的时候学习过双曲函数...额,暴露了... 原文地址:https://zhuanlan.zhihu.com/p/20042215 可能是最好的讲解双曲函数的文章 零.写在前面 (近期 ...