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;
}