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

posted @ 2020-03-26 15:15  Lates  阅读(119)  评论(0编辑  收藏  举报