字串距离
luogu 1279
题目大意
给出两个字符串,让你加上若干空格,使其长度相同
对于第i位,如果都是字母那代价就是ASCII码的差值,如果一个是字母那就是k,如果没有一个是字母那就是0,让你求最小代价
输入样例
cmc
snmn
2
输出样例
10
数据范围
∣S∣⩽2000,1⩽K⩽100|S|\leqslant 2000,1\leqslant K\leqslant 100∣S∣⩽2000,1⩽K⩽100
解题思路
设fi,jf_{i,j}fi,j为字符串A前i个字符和字符串B前j个字符匹配的最小代价
那么有:
fi,j=min{fi−1,j−1+abs(s1i−s2j),fi−1,j+k,fi,j−1+k}f_{i,j}=min\{ f_{i-1,j-1}+abs(s1_i-s2_j),f_{i-1,j}+k,f_{i,j-1}+k\}fi,j=min{fi−1,j−1+abs(s1i−s2j),fi−1,j+k,fi,j−1+k}
第一个是两个字符匹配,后面是和空格匹配(两个空格匹配没有贡献,所以不用管)
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 2010
using namespace std;
int k, l1, l2, f[N][N];
string str1, str2;
int abss(int x)
{return x < 0 ? -x : x;
}
int main()
{cin>>str1;cin>>str2;l1 = str1.size();l2 = str2.size();str1 = ' ' + str1;str2 = ' ' + str2;scanf("%d", &k);memset(f, 127/3, sizeof(f));f[0][0] = 0;for (int i = 1; i <= l1; ++i)f[i][0] = k * i;for (int i = 1; i <= l2; ++i)f[0][i] = k * i;for (int i = 1; i <= l1; ++i)for (int j = 1; j <= l2; ++j)f[i][j] = min(f[i - 1][j - 1] + abss(str1[i] - str2[j]), min(f[i - 1][j] + k, f[i][j - 1] + k));printf("%d", f[l1][l2]);return 0;
}