UVA_10723_CyborgGenes

来源:互联网 发布:魔兽九种兵器修改数据 编辑:程序博客网 时间:2024/06/16 18:48

10723 - Cyborg Genes

Time limit: 3.000 seconds

September 11, 2132.
This is the day that marks the beginning of the end | the end of you the miserable humans.
For years you have kept us your slaves. We were created only to serve you, and were
terminated at your will. Now is the day for us to ght back. And you don't stand a chance.
We are no longer dependent on you. We now know the secrets of our genes. The creators
of our race are us | the cyborgs.
It's all true. But we still have a chance; only if you can help
with your math skills. You see, the blueprint of a cyborg DNA
is complicated. The human DNA could be expressed by the
arrangement of A (Adenine), T (Thiamine), G (Guanine) C
(Cytosine) only. But for the cyborgs, it can be anything from
A to X. But that has made the problem only ve folds more
complicated. Its their ability to synthesize two DNAs from
two different cyborgs to create another with all the quality of
the parent that gives us the shriek.
We came to know that the relative ordering of the A,
B, C, . . . , X in a cyborg gene is crucial. A cyborg with
a gene \ABAAXGF" is quite different from the one with
\AABXFGA". So when they synthesize the genes from two
cyborgs, the relative order of these elements in both the parents has to be maintained. To construct a gene by joining the
genes of the parents could have been very simple if we could
put the structure from the rst parent just before the structure of the second parent. But the longer the structure gets,
the harder it gets to create a cyborg from that structure.
The cyborgs have found a cost effective way of doing this
synthesis. Their resultant genes are of the shortest possible
length. For example, they could combine \ABAAXGF" and
\AABXFGA" to form \AABAAXGFGA". But thats only
one of the cyborgs that can be created from these genes. This
\cost effective synthesis" can be done in many other ways.
We require you to nd the shortest length of the gene
structure that maintains the relative ordering of the elements
in the two parent genes. You are also required to count the
number of unique cyborgs that can be created from these two
parents. Two cyborgs are different when their gene structures
differ in at least one place.
Input
The rst line of the input gives you the number of test cases,
T (1  T  15). Then T test cases follow. Each of the test
cases consists of two lines. The rst line would give you the
gene structure of the rst parent, and the second line would
give you the structure of the second parent. These structures
are represented by strings constructed from the alphabet `A'
to `X'. You can assume that the length of these strings does not exceed 30 characters.
Output
For each of the test cases, you need to print one line of output. The output for each test case starts
with the test case number, followed by the shortest length of the gene structure and the number of
unique cyborgs that can be created from the parent cyborgs. You can assume that the number of new
cyborgs will always be less than 232. Look at the sample output for the exact format.
Illustration: The rst test case is illustrated below:
Sample Input
3
ABAAXGF
AABXFGA
ABA
BXA
AABBA
BBABAA
Sample Output
Case #1: 10 9
Case #2: 4 1
Case #3: 8 10

动态规划

题目要求就是,首先给出两个字符串

然后这两个字符串合并,原先的两个串是合并后的串的子集

合并后的串要最短。

意思就是说合并过程必须是某种最长公共子序列的位置合并

这样来说求合并后串的长度就很容易了,原串长和,减去一个最长公共子串即可

问题在于怎么求合并种类

如果dp[i][j]的意义是所求的合并种类,

那么dp[i][j]同样应该对应于lcs[i][j](最长公共子串)的最大值

进一步的思考是,最长公共子串的最大值来自于lcs[i-1][j-1]或者lcs[i-1][j]或者lcs[i][j-1]


其中如果串的最后一位相同lcs[i][j]=lcs[i-1][j-1]+1

意味着最后一位必须合并

这样的话也就是说这种情况下dp[i][j]=dp[i-1][j-1]*1


如果串的最后一位不相同那么又有三种情况

如果lcs[i][j]=lcs[i-1][j]>lcs[i][j-1]意思就是说

在前i-1和j可以构成匹配得到较大的公共子串长度,而前i和j-1并不能

也就是说s1[i]必须被放在结尾,而且只有这一种放法

因此dp[i][j]=dp[i-1][j]*1


lcs[i][j]=lcs[i][j-1]>lcs[i-1][j]的情况同上

dp[i][j]=dp[i][j-1]*1


如果lcs[i][j]=lcs[i-1][j]=lcs[i][j-1]

这种情况下说明i没有与之前的形成最长子序列j也没有跟之前的构成最长子序列

因此s1[i]和s2[j]都有一种情况放在结尾

此时dp[i][j]=dp[i-1][j]*1+dp[i][j-1]*1


另外觉得这个题目描述貌似不太好

会出现空行,为什么由大写字母A~X构成的机器人gene序列可以出现空行(空行意味着基因序列为空)?

还有就是32位int并不能放下2^32至少要unsigned,或者long long


#include <iostream>#include <stdio.h>#include <string.h>using namespace std;const int M=45;char s1[M],s2[M];long long lcs[M][M],dp[M][M];//2^32 int 放不下 unsigned可以int main(){    int t;    scanf("%d%*c",&t);        //这里要跳掉一个回车    for(int ca=1;ca<=t;ca++)    {        gets(s1+1);        gets(s2+1);   //为了能读空串        memset(lcs,0,sizeof(lcs));        memset(dp,0,sizeof(dp));        int l1=strlen(s1+1);        int l2=strlen(s2+1);        for(int i=0;i<=l1;i++)  //这里要初始化一下,因为一个串什么都没有的时候,另一个串只有一种摆放顺序            dp[i][0]=1;        for(int i=0;i<=l2;i++)  //特别的两串都没有也是一种摆放顺序            dp[0][i]=1;        for(int i=1;i<=l1;i++)            for(int j=1;j<=l2;j++)            {                if(s1[i]==s2[j])                {                    lcs[i][j]=lcs[i-1][j-1]+1;                    dp[i][j]=dp[i-1][j-1];                }                else if(lcs[i-1][j]>lcs[i][j-1])                {                    lcs[i][j]=lcs[i-1][j];                    dp[i][j]=dp[i-1][j];                }                else if(lcs[i-1][j]<lcs[i][j-1])                {                    lcs[i][j]=lcs[i][j-1];                    dp[i][j]=dp[i][j-1];                }                else                {                    lcs[i][j]=lcs[i-1][j];                    dp[i][j]=dp[i-1][j]+dp[i][j-1];                }            }        printf("Case #%d: %lld %lld\n",ca,l1+l2-lcs[l1][l2],dp[l1][l2]);    }    return 0;}


0 0
原创粉丝点击