Fork me on GitHub

POJ3356-AGTC(最短编辑距离)

POJ3356-AGTC(最短编辑距离)

题意

多测,每次给出两个长度分别为n和m的字符串s1,s2,有三种操作:增加、删除、修改一个字符,问将s1变成s2,最少要几次操作。

题解

dp[i][j]表示将s1的前i个字符变成s2的前j个字符所需要的最小操作数。
考虑dp[i][j]的三种来源:
1、s1中删除一个字符,那么dp[i][j]=dp[i-1][j]+1。
2、s1中增加一个字符,那么dp[i][j]=dp[i][j-1]+1。
3、修改。如果\(s1[i]=s2[j]\),dp[i][j]=dp[i-1][j-1],如果\(s1[i] \neq s2[j]\),dp[i][j]=dp[i-1][j-1]+1。
dp[i][j]取三种操作中最小的。

代码

#include<iostream>
#include<cstdio>

using namespace std;
typedef long long ll;
const int N=1e3+10;
int n,m;
char s1[N],s2[N];
ll dp[N][N];
int main(){
	while(scanf("%d%s%d%s",&n,s1+1,&m,s2+1)!=EOF){
		for(int i=1;i<=m;i++) dp[0][i]=i;
		for(int i=1;i<=n;i++) dp[i][0]=i;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				int x;
				if(s1[i]==s2[j]) x=0;
				else x=1;
				dp[i][j]=min(dp[i-1][j]+1,min(dp[i][j-1]+1,dp[i-1][j-1]+x));
			}
		}
		printf("%lld\n",dp[n][m]);
	}
	return 0;
}
posted @ 2020-03-19 15:52  qjy_73  阅读(109)  评论(0)    收藏  举报