• uva 10723 Cyborg Genes(LCS变形)


    题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=107450#problem/C

    题意:输入两个字符串,找一个最短的串,使得输入的两个串均是他的子序列,统计长度最短的串的个数;

    分析:最短串的长度就等于a串长度 + b串长度 - LCS( a, b )

    借鉴于

    c[i][j]表示a串前i个元素和b串前j个元素所能得到的方案数。l[i][j]表示LCS的长度

    若a[i]=b[j],那么c[i][j]=c[i-1][j-1],即a串前i-1个元素和b串前j-1个元素得到的组合串的末尾加上一个相同的元素a[i],那么得到的新的组合串的个数还是和之前的组合串的个数一样

    若a[i]!=b[j],  l[i][j]=max { l[i-1][j] , l[i][j-1]}

    若l[i-1][j]>l[i][j-1],那说明从l[i-1][j]这种状态开始构建才能得到最终的LCS同时最终的组合串才不能漏掉共有的元素,所以c[i][i]=c[i-1][j],即在a串i-1个元素和b串j个元素组成的组合串的后面加上a[i],那么得到的新的组合串的个数和之前的组合串的个数是相同的

    若l[i][j-1]>l[i-1][j],道理和上面是一样的,所以c[i][j]=c[i][j-1],相当于在之前的组合串后面加上元素b[j],得到新的组合串的个数不变

    若l[i][j-1]=l[i-1][j],说明从两种状态都是能得到最终的LCS并且最终的组合串不会漏掉任何相同的公共元素,所以c[i][j]=c[i-1][j]+c[i][j-1] , 即用a串的i-1个元素和b串的j个元素组成的组合串的最后加上a[i]得到新的组合串和之前的组合串个数相同,另外用a串的i个元素和b串的的j-1个元素组成的组合串的最后加上b[j]得到新的组合串和之前的组合串个数相同,那么就是两者之和

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <cstdio>
     5 using namespace std;
     6 const int Max = 50;
     7 char a[Max],b[Max];
     8 int c[Max][Max],l[Max][Max],B[Max][Max];
     9 /*
    10 void print(int i, int j)
    11 {
    12     if(i == 0 && j == 0)
    13         return;
    14     if(i == 0)
    15     {
    16         for(int k = 1; k <= j; k++)
    17             printf("%c", b[k]);
    18         return;
    19     }
    20     if (j == 0)
    21     {
    22         for(int k = 1; k <= i; k++)
    23             printf("%c", a[k]);
    24         return;
    25     }
    26     if(B[i][j] == 0)
    27     {
    28         print(i - 1, j - 1);
    29         printf("%c", a[i]);
    30     }
    31     else if(B[i][j] == 1)
    32     {
    33         print(i - 1, j);
    34         printf("%c", a[i]);
    35     }
    36     else
    37     {
    38         print(i, j - 1);
    39         printf("%c", b[j]);
    40     }
    41 }
    42 */
    43 int main()
    44 {
    45     int test;
    46     scanf("%d", &test);
    47     getchar();
    48     for(int t = 1; t <= test; t++)
    49     {
    50         gets(a + 1);
    51         gets(b + 1);
    52         int lena = strlen(a + 1);
    53         int lenb = strlen(b + 1);
    54         for(int i = 0; i <= lena; i++)
    55         {
    56             for(int j = 0; j <= lenb; j++)
    57                 c[i][j] = 1;
    58         }
    59         memset(l, 0, sizeof(l));
    60         memset(B, 0, sizeof(b));
    61         for(int i = 1; i <= lena; i++)
    62         {
    63             for(int j = 1; j <= lenb; j++)
    64             {
    65                 if(a[i] == b[j])
    66                 {
    67                     l[i][j] = l[i - 1][j - 1] + 1;
    68                     c[i][j] = c[i - 1][j - 1];
    69                     B[i][j] = 0;
    70                 }
    71                 else
    72                 {
    73                     l[i][j] = max(l[i - 1][j], l[i][j - 1]);
    74                     if(l[i - 1][j] > l[i][j - 1])
    75                     {
    76                         c[i][j] = c[i - 1][j];
    77                         B[i][j] = 1;
    78                     }
    79                     else if(l[i - 1][j] < l[i][j - 1])
    80                     {
    81                         c[i][j] = c[i][j - 1];
    82                         B[i][j] = -1;
    83                     }
    84                     else
    85                     {
    86                         c[i][j] = c[i - 1][j] + c[i][j - 1];
    87                     }
    88                 }
    89             }
    90         }
    91         printf("Case #%d: %d %d
    ", t, lena + lenb - l[lena][lenb], c[lena][lenb]);
    92 
    93     }
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    【算法研究】排序算法
    20121031 学习心得与体会
    循环有序数组查找(log(n))
    XmlDocument创建XML文档
    GCC地址对齐的2个方法
    打印getaddrinfo()返回的地址信息
    Java单例模式
    二叉搜索树的例子BST
    XmlTextWriter创建XML文档
    XmlDocument读取XML文档
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5222479.html
Copyright © 2020-2023  润新知