题目大意:
定义两个等长的字符串
a,b
的差为
dist=∑g[ai][bi]
。现已给出两个子串
α,β
,定义
D(α,β)
为两个分别包含
α,β
的等长串
a,b
的差。求
D(α,β)
的最小值与串
a,b
。
分析:
简单
DP
即可额
...
设
f[i][j]
表示
α,β
分别已经匹配了
i,j
位的差的最小值,那么有:
f[i][j]=min⎧⎩⎨⎪⎪⎪⎪f[i−1][j]+min{g[αi][p]}f[i][j−1]+min{g[p][βj]}f[i−1][j−1]+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;
}