luogu P1279 字串距离
一道类似于最长公共子序列做法的dp题。
题意就是给两个字符串,可以在中间添加空格,求最小距离。
设 \(f_{i,j}\) 为 \(A\) 从 \(1-i\) 的子串和 \(B\) 从 \(1-j\) 的子串的距离。
则分为 \(3\) 种情况 \(:\)
- 不加空格,则 \(f_{i,j}=f_{i-1,j-1}+clac(A_i,B_i)\),\(clac(A_i,B_i)\)即为\(A_i,B_i\)需要付出的代价,即为 \(|A_i-B_i|\)
- 在 \(A\) 加空格,则 \(f_{i,j}=f_{i-1,j}+k\)
- 在 \(B\) 加空格,则 \(f_{i,j}=f_{i,j-1}+k\)
\(Code\)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
inline int read(){
register int x=0,f=0,ch=getchar();
while('0'>ch||ch>'9')f^=ch=='-',ch=getchar();
while('0'<=ch&&ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
return f?-x:x;
}
#define _min(a,b) a<b?a:b
#define abs(a,b) ((int)a>(int)b?(int)(a-b):(int)(b-a))
const int MAX=2005;
string a,b;int k;
int f[MAX][MAX];
signed main(){
cin>>a>>b;k=read();
a=' '+a,b=' '+b;
memset(f,0x3f,sizeof(f));f[0][0]=0;
for(register int i=1;i<=a.length();++i)f[i][0]=i*k;
for(register int i=1;i<=b.length();++i)f[0][i]=i*k;
for(register int i=1;i<=a.length();++i){
for(register int j=1;j<=b.length();++j){
f[i][j]=_min(f[i-1][j-1]+abs(a[i],b[j]),f[i][j]);
f[i][j]=_min(f[i-1][j]+k,f[i][j]);
f[i][j]=_min(f[i][j-1]+k,f[i][j]);
}
}
printf("%d\n",f[a.length()][b.length()]);
return 0;
}