• UVA10723 电子人的基因


    UVA10723 电子人的基因

    题目比较难找附上链接:https://vjudge.net/problem/UVA-10723

    题目描述:

    给你两个字符串,你需要找出一个最短的字符串,使得两个给定字符串都是找出字符串的子序列

    同时,还要找出这个最短的字符串的组成方案有几种。

    多组数据,输出格式见样例。

    样例输入:

    3

    ABAAXGF

    AABXFGA

    ABA

    BXA

    AABBA

    BBABAA

    样例输出:

    Case #1: 10 9

    Case #2: 4 1

    Case #3: 8 10

    题目分析:

    首先不考虑寻找的串最短,只考虑使两个串均为找到的串的自序

    那么很显然,我们可以直接将两个给定的字符串拼接起来,得到答案

    到了这里,我们可以考虑,在这个拼接的串中,删去一些不必要的字符,来得到最优解

    考虑可以删去的字符,一定同时两个串中,位置任意,所以,只要删去两个串的最长公共子序列即可

    最优解的字符串长度 = len1 + len2 - len_(lcs(a,b))

    考虑维护f[i][j](LCS)的同时维护g[j][j](a串匹配到i位,b串到第j位,最优解的方案数)

    转移的时候,f从哪里转移,g必然也从什么地方转移(详见代码)

    注:原题面数据丧心病狂卡了读入,两个字符串中存在空格这种东西,不能用scanf,用gets即可

    CODE:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 
     6 #define RI register int
     7 using namespace std;
     8 typedef long long ll;
     9 
    10 const int INF = 1e9 + 7;
    11 const int MAXN = 50 + 5;
    12 
    13 #define max(a,b) ((a) > (b) ? (a) : (b))
    14 #define min(a,b) ((a) < (b) ? (a) : (b))
    15 
    16 inline void read(int &x)
    17 {
    18     x = 0;
    19     bool flag = 0;
    20     char ch = getchar();
    21     while(ch < '0' || ch > '9')
    22     {
    23         if(ch == '-')    flag = 1;
    24         ch = getchar();
    25     }
    26     while(ch >= '0' && ch <= '9')
    27     {
    28         x = x * 10 + ch - '0';
    29         ch = getchar();
    30     }
    31     if(flag)    x *= -1;
    32 }
    33 
    34 int T,len1,len2,t;
    35 char a[MAXN],b[MAXN];
    36 ll f[MAXN][MAXN],g[MAXN][MAXN];
    37 
    38 void init()
    39 {
    40     memset(f,0,sizeof(f));
    41     memset(g,0,sizeof(g));
    42     memset(a,0,sizeof(a));
    43     memset(b,0,sizeof(b));
    44     //scanf("%s",a + 1);
    45     //scanf("%s",b + 1);
    46     gets(a + 1);
    47     gets(b + 1);
    48     len1 = strlen(a + 1);
    49     len2 = strlen(b + 1);
    50 }
    51 
    52 int main()
    53 {
    54     read(T);
    55     while(T --)
    56     {
    57         init();
    58         for(int i = 0;i <= max(len1,len2);i ++)
    59             g[i][0] = g[0][i] = 1;
    60         for(RI i = 1;i <= len1;i ++)
    61         {
    62             for(RI j = 1;j <= len2;j ++)
    63             {
    64                 if(a[i] == b[j])
    65                 {
    66                     f[i][j] = f[i - 1][j - 1] + 1;
    67                     g[i][j] += g[i - 1][j - 1];
    68                 }
    69                 else
    70                 {
    71                     f[i][j] = max(f[i - 1][j],f[i][j - 1]);
    72                     if(f[i - 1][j] > f[i][j - 1])
    73                         g[i][j] += g[i - 1][j];
    74                     else if(f[i - 1][j] < f[i][j - 1])
    75                         g[i][j] += g[i][j - 1];
    76                     else
    77                         g[i][j] += g[i - 1][j] + g[i][j - 1];
    78                 }
    79             }
    80         }
    81         printf("Case #%d: %lld %lld
    ",++ t,len1 + len2 - f[len1][len2],g[len1][len2]);
    82     }
    83     
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    CSS
    JavaScript
    Spring
    【Linux__FTP】Linux安装ftp组件
    【SSM__分页】MyBatis 分页插件
    【SSM__utils】实用代码风格收录
    【SSM__整合】ssm整合思路
    【Spring__父子容器】Spring父子容器关系
    stm32定时器_输出比较+输入捕获
    Redis的安装和基本操作01
  • 原文地址:https://www.cnblogs.com/illyaillyasviel/p/7711358.html
Copyright © 2020-2023  润新知