Description
给出两个由小写字母组成的字符串 X 和Y ,我们需要算出两个字符串的距离,定义如下:
1) 我们可以在字符串的头、尾、中间插入若干空格,组成一个新的扩展串
2) 对X扩展成扩展串X1,对Y扩展成扩展串Y1,并且令X1和Y1具有相同的长度
3) 定义X1、Y1的距离为每个对应的字符的距离之和,其中两个空格的距离为0,两个非空格字符的距离为其ASCII码之差的绝对值,一个空格字符到任意非空格字符的距离为K
4) 对于字符串X、Y,必然存在两个等长的扩展串X1、Y1,使得X1、Y1的距离达到最少,我们将这一距离定义为字符串X、Y的距离
Input
输入为三行,前两行是30位以内的由小写字母组成的字符串, 第三行是整数K(0<=K<=30)
Output
输出一行为一个整数,代表两个字符串的距离
cmo
snmn
2
-
Sample Input
7
-
Sample Output
直接DP
求匹配到si和tj的最优解。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 35;
char sa[MAXN], sb[MAXN]; int dp[MAXN][MAXN];
int abs(int x) { // 绝对值
return (x<0)?-x:x;
}
int main() {
int val; scanf("%s%s%d", sa+1, sb+1, &val); int la=strlen(sa+1), lb=strlen(sb+1);
for (int i=1; i<=la; ++i) dp[i][0] = dp[i-1][0]+val; // 显而易见的,另一个串还都是空格
for (int i=1; i<=lb; ++i) dp[0][i] = dp[0][i-1]+val;
for (int i=1; i<=la; ++i) {
for (int j=1; j<=lb; ++j) dp[i][j] = min(dp[i-1][j-1]+abs(sa[i]-sb[j]),min(dp[i-1][j],dp[i][j-1])+val); // 三种情况:只要s的,只要t的,两个一起要的
}
printf("%d", dp[la][lb]);
return 0;
}