• UVA 10723 Cyborg Genes


    UVA_10723

        首先这个题目肯定是按最长公共子序列的形式进行dp的,因为只有保证消去的一部分是最长公共子序列才能保证最后生成的序列最短。

        因此,在记录方案数的时候我们也按最长公共子序列的生成过程来记录即可,我们不妨用p[i][j]记录最长公共子序列的字符数,用f[i][j]表示到第一个字符串第i个位置、第二个字符串第j个位置时生成的序列最短的方案种数。

        当a[i]!=b[j]时,p[i][j]=max{p[i-1][j],p[i][j-1]},那么如果p[i][j]==p[i-1][j],f[i][j]+=f[i-1][j],如果p[i][j]==p[i][j-1],f[i][j]+=f[i][j-1]。用文字翻译过来就是说因为a[i]和b[j]是不同的,所以f[i][j]等于以a[i]结尾的最短的字符串的方案种数,加上以b[j]结尾的最短的字符串的方案种数。

        当a[i]==b[j]时,p[i][j]=p[i-1][j-1]+1,f[i][j]+=f[i-1][j-1]。试想,我们这样算会不会少算某些部分呢?因为毕竟也可以在a[i]和b[j]不配成一对的情况下生成最短的字符串呀。实际上,是可以证明f[i-1][j-1]包含了上述的情况的。譬如我们假设b[j]和a[i]前面的某个字符配成一对,同时生成了最短的字符串,那么这个字符串必然是以a[i]结尾的某个最短字符串,而以a[i]结尾的所有最短字符串的个数显然已经包含在f[i-1][j-1]之中了,因为f[i-1][j-1]本身就表示的是以a[i]为结尾的最短字符串的方案总数。

        实际上,这个类似证明求最长公共子序列时如果a[i]==b[j],那么取p[i][j]=p[i-1][j-1]+1一定是最优的。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 35
    #define INF 1000000000
    char a[MAXD], b[MAXD], p[MAXD][MAXD];
    long long int f[MAXD][MAXD];
    void solve()
    {
    int i, j, k, lena, lenb, len;
    gets(a + 1);
    gets(b + 1);
    lena = strlen(a + 1);
    lenb = strlen(b + 1);
    memset(f, 0, sizeof(f));
    for(i = 0; i <= lena; i ++)
    for(j = 0; j <= lenb; j ++)
    p[i][j] = INF;
    for(i = 0; i <= lenb; i ++)
    {
    f[0][i] = 1;
    p[0][i] = 0;
    }
    for(i = 0; i <= lena; i ++)
    {
    f[i][0] = 1;
    p[i][0] = 0;
    }
    for(i = 1; i <= lena; i ++)
    for(j = 1; j <= lenb; j ++)
    {
    if(a[i] == b[j])
    {
    p[i][j] = p[i - 1][j - 1] + 1;
    f[i][j] += f[i - 1][j - 1];
    }
    else
    {
    p[i][j] = p[i - 1][j] > p[i][j - 1] ? p[i - 1][j] : p[i][j - 1];
    if(p[i - 1][j] == p[i][j])
    f[i][j] += f[i - 1][j];
    if(p[i][j - 1] == p[i][j])
    f[i][j] += f[i][j - 1];
    }
    }
    printf("%d %lld\n", lena + lenb - p[lena][lenb], f[lena][lenb]);
    }
    int main()
    {
    int t, tt;
    gets(b);
    sscanf(b, "%d", &t);
    for(tt = 0; tt < t; tt ++)
    {
    printf("Case #%d: ", tt + 1);
    solve();
    }
    return 0;
    }


  • 相关阅读:
    Restful API 指南
    git submodule 使用小结
    git 在 A 项目中引用 B 项目
    Error Permission denied when running brew cleanup
    @Scope注解设置创建bean的方式和生命周期
    spring常用注解
    Spring的AOP配置文件和注解实例解析
    java线程的状态
    java线程执行的优先级
    java创建线程的方法
  • 原文地址:https://www.cnblogs.com/staginner/p/2278307.html
Copyright © 2020-2023  润新知