• SGU 214 Weird Dissimilarity


    SGU_214

        这个题目和最长公共子序列dp的过程是类似的,可以用f[i][j]表示λ匹配到i,μ匹配到j时的最优解。那么f[i][j]只会由三种情况得到:一种情况是λ[i]和某个字符去匹配(显然应该和匹配后增加的值最小的字符去匹配),一种情况是μ[j]和某个字符去匹配(也应该和匹配后增加的值最小的字符去匹配),还有一种情况是λ[i]和μ[j]匹配。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 2010
    #define INF 0x7fffffff
    char a[MAXD], b[MAXD], alph[300];
    long long int f[MAXD][MAXD];
    int N, Na, Nb, mina[MAXD], minb[MAXD], g[MAXD][MAXD], p[MAXD][MAXD];
    int c[600], *ch, ansa[2 * MAXD], pa, ansb[2 * MAXD], pb;
    void init()
    {
    int i, j, k;
    ch = &c[300];
    N = strlen(alph + 1);
    gets(a + 1);
    Na = strlen(a + 1);
    gets(b + 1);
    Nb = strlen(b + 1);
    for(i = 1; i <= N; i ++)
    ch[alph[i]] = i;
    for(i = 1; i <= N; i ++)
    {
    k = INF;
    for(j = 1; j <= N; j ++)
    {
    scanf("%d", &g[i][j]);
    if(g[i][j] <= k)
    k = g[i][j], mina[i] = j;
    }
    }
    for(j = 1; j <= N; j ++)
    {
    k = INF;
    for(i = 1; i <= N; i ++)
    if(g[i][j] <= k)
    k = g[i][j], minb[j] = i;
    }
    }
    void dfs(int na, int nb)
    {
    if(na == 0 && nb == 0)
    return ;
    if(p[na][nb] == 0)
    {
    ansa[pa ++] = ch[a[na]], ansb[pb ++] = ch[b[nb]];
    dfs(na - 1, nb - 1);
    }
    else if(p[na][nb] > 0)
    {
    ansa[pa ++] = ch[a[na]], ansb[pb ++] = p[na][nb];
    dfs(na - 1, nb);
    }
    else
    {
    ansa[pa ++] = -p[na][nb], ansb[pb ++] = ch[b[nb]];
    dfs(na, nb - 1);
    }
    }
    void printresult()
    {
    int i, j, k;
    pa = pb = 0;
    dfs(Na, Nb);
    printf("%I64d\n", f[Na][Nb]);
    while(pa)
    printf("%c", alph[ansa[-- pa]]);
    printf("\n");
    while(pb)
    printf("%c", alph[ansb[-- pb]]);
    printf("\n");
    }
    void solve()
    {
    int i, j, k, x, y;
    long long int t;
    f[0][0] = 0;
    t = 0;
    for(i = 1; i <= Na; i ++)
    {
    x = ch[a[i]];
    f[i][0] = f[i - 1][0] + g[x][mina[x]], p[i][0] = mina[x];
    }
    t = 0;
    for(i = 1; i <= Nb; i ++)
    {
    y = ch[b[i]];
    f[0][i] = f[0][i - 1] + g[minb[y]][y], p[0][i] = -minb[y];
    }
    for(i = 1; i <= Na; i ++)
    for(j = 1; j <= Nb; j ++)
    {
    x = ch[a[i]], y = ch[b[j]];
    f[i][j] = f[i - 1][j - 1] + g[x][y], p[i][j] = 0;
    if(f[i - 1][j] + g[x][mina[x]] < f[i][j])
    f[i][j] = f[i - 1][j] + g[x][mina[x]], p[i][j] = mina[x];
    if(f[i][j - 1] + g[minb[y]][y] < f[i][j])
    f[i][j] = f[i][j - 1] + g[minb[y]][y], p[i][j] = -minb[y];
    }
    printresult();
    }
    int main()
    {
    gets(alph + 1);
    init();
    solve();
    return 0;
    }


  • 相关阅读:
    JAVA 异常
    JAVA 接口的基本语法
    JAVA 访问权限
    Linux shell 函数应用示例02
    Linux shell 函数应用示例01
    Linux shell while循环语句
    Linux shell 中断循环语句
    Linux shell for循环结构
    测试用例基本概念
    软件测试原则
  • 原文地址:https://www.cnblogs.com/staginner/p/2431572.html
Copyright © 2020-2023  润新知