uva 10723 - Cyborg Genes

Problem F

Cyborg Genes

Time Limit

1 Second

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 fight 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 five folds more complicated. It’s 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 first 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 that’s 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 find 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 first 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 first line would give you the gene structure of the first 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.

Sample Input

Output for Sample Input

3
ABAAXGF
AABXFGA
ABA
BXA
AABBA
BBABAA

Case #1: 10 9
Case #2: 4 1
Case #3: 8 10




这道题目其实是LCS的变型,LCS的还有一个用处是用来求最小编辑距离x(将两个字符串变成一个字符串的最少插入次数),有公式x=m+n-2*LCS(m,n)。

那么最后的字符串长度为x+LCS(m,n)=m+n-LCS(m,n)。

这题还要求方案数,可以模仿LCS的解法,dp[i][j]表示串a的前i个字符和串b的前j个字符的组成最短的字符串的方案数。首先可以肯定最短字符串必定是以a[i]或者b[i],否则可以去掉这个字符。

如果a[i]==b[j],那么根据上述结论最后一个字符就是a[i]了,去掉a[i],那么剩余字符串就是a的前i-1个字符和b的前j-1个字符的方案数。

如果a[i]!=b[j],那么这个时候要看LCS数组了,可以计算a的前i个字符和串b的前j个字符的组成最短的字符串的长度为i+j-LCS[i][j]。

如果组成最短的字符串以a[i]结尾,那么去掉a[i],最短的字符串的长度为i+j-LCS[i][j]-1,并且等于i-1+j-LCS[i-1][j],这样说明LCS[i][j]=LCS[i-1][j];同理如果组成最短的字符串以b[j]结尾,那么有LCS[i][j]=LCS[i][j-1].

而实际LCS[i][j]=max(LCS[i-1][j],LCS[i][j-1]),因此又得分三种情况。

1.LCS[i-1][j]>LCS[i][j-1],此时相当于a[i]结尾了,因此dp[i][j]=dp[i-1][j];

2.LCS[i-1][j]<LCS[i][j-1],此时相当于b[j]结尾了,因此dp[i][j]=dp[i][j-1];

3.LCS[i-1][j]=LCS[i][j-1],此时相当于a[i]或者b[j]结尾了,因此有两种决策添字母,根据加法原理,就是dp[i][j]=dp[i-1][j]+dp[i][j-1];

注意此题有些问题:需用gets()读入。


代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

char a[40],b[40];
int dp1[40][40];
long long dp2[40][40];
int main()
{
    int t,cas=1;
    scanf("%d%*c",&t);
    while(t--){
        gets(a+1);
        gets(b+1);
        int la=strlen(a+1),lb=strlen(b+1);
        for(int i=0;i<=lb;i++) dp1[0][i]=0,dp2[0][i]=1;
        for(int i=1;i<=la;i++) dp1[i][0]=0,dp2[i][0]=1;
        for(int i=1;i<=la;i++)
            for(int j=1;j<=lb;j++)
                if(a[i]==b[j]){
                    dp1[i][j]=dp1[i-1][j-1]+1;
                    dp2[i][j]=dp2[i-1][j-1];
                }
                else{
                    dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]);
                    if(dp1[i-1][j]>dp1[i][j-1])
                        dp2[i][j]=dp2[i-1][j];
                    else if(dp1[i-1][j]<dp1[i][j-1])
                        dp2[i][j]=dp2[i][j-1];
                    else
                        dp2[i][j]=dp2[i-1][j]+dp2[i][j-1];
                }
        printf("Case #%d: ",cas++);
        printf("%d %lld\n",la+lb-dp1[la][lb],dp2[la][lb]);
    }
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值