sgu214:Weird Dissimilarity(DP)

来源:互联网 发布:安全生产网络知识竞赛 编辑:程序博客网 时间:2024/05/29 04:18

题目大意:
      定义两个等长的字符串a,b的差为dist=g[ai][bi]。现已给出两个子串α,β,定义D(α,β)为两个分别包含α,β的等长串a,b的差。求D(α,β)的最小值与串a,b

分析:
      简单DP即可额...
      f[i][j]表示α,β分别已经匹配了i,j位的差的最小值,那么有:
             f[i][j]=minf[i1][j]+min{g[αi][p]}f[i][j1]+min{g[p][βj]}f[i1][j1]+g[αi][βj]

其中1,2行的min可以预处理,总的时间复杂度就是O(n2)

AC code:

#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <iostream>#define ONLINE_JUDGE using namespace std;const int SIGMA = 209;const int MAXN = 2009;int n;char src[SIGMA];char s1[MAXN], s2[MAXN];int ls, l1, l2;int g[SIGMA][SIGMA];int min1[SIGMA], min2[SIGMA];int cn[300];int f[MAXN][MAXN];int from[MAXN][MAXN];string ans1, ans2;int main(){    #ifndef ONLINE_JUDGE    freopen("sgu214.in", "r", stdin);    freopen("sgu214.out", "w", stdout);    #endif    scanf("%s%s%s", src, s1, s2);    ls = strlen(src), l1 = strlen(s1), l2 = strlen(s2);    for(int i = 0; i < ls; ++i)        cn[(int)src[i]] = i;    for(int i = 0; i < ls; ++i)        for(int j = 0; j < ls; ++j)        {            scanf("%d", &g[i][j]);            if(g[i][min1[i]] > g[i][j])                min1[i] = j;            if(g[min2[j]][j] > g[i][j])                min2[j] = i;            }    for(int i = 1; i <= l1; ++i)    {        f[i][0] = f[i-1][0]+g[cn[s1[i-1]]][min1[cn[s1[i-1]]]];        from[i][0] = 1;    }    for(int i = 1; i <= l2; ++i)    {        f[0][i] = f[0][i-1]+g[min2[cn[s2[i-1]]]][cn[s2[i-1]]];        from[0][i] = 2;    }    for(int i = 1; i <= l1; ++i)        for(int j = 1; j <= l2; ++j)        {            int sum1 = f[i-1][j]+g[cn[s1[i-1]]][min1[cn[s1[i-1]]]];            int sum2 = f[i][j-1]+g[min2[cn[s2[j-1]]]][cn[s2[j-1]]];            int sum3 = f[i-1][j-1]+g[cn[s1[i-1]]][cn[s2[j-1]]];            f[i][j] = min(min(sum1, sum2), sum3);            if(f[i][j] == sum1) from[i][j] = 1;            else if(f[i][j] == sum2) from[i][j] = 2;            else from[i][j] = 3;        }    printf("%d\n", f[l1][l2]);    for(int i = l1, j = l2; i || j;)    {        switch(from[i][j])        {            case 1:ans1 += s1[i-1];ans2 += src[min1[cn[s1[i-1]]]];--i;break;            case 2:ans1 += src[min2[cn[s2[j-1]]]];ans2 += s2[j-1];--j;break;            case 3:ans1 += s1[i-1];ans2 += s2[j-1];--i;--j;break;        }    }    for(int i = ans1.size()-1; i >= 0; --i)        putchar(ans1[i]);    puts("");    for(int i = ans2.size()-1; i >= 0; --i)        putchar(ans2[i]);    puts("");    #ifndef ONLINE_JUDGE    fclose(stdin);    fclose(stdout);    #endif    return 0;   }
0 0