字符串编辑(动态规划)

题目

给定两个字符串 s t r 1 str1 s t r 2 str2 ,再给定三个整数 i c ic d c dc 、和 r c rc 分别代表插入、删除和替换一个字符的代价。返回将 s t r 1 str1 编辑成 s t r 2 str2 的最小代价。

比如, s t r 1 = a b c str1=“abc” s t r 2 = a d c str2=“adc” i c = 5 ic=5 d c = 3 dc=3 r c = 2 rc=2 。把 b b 替换成 d d 是代价最小的,所以返回 2 2

再比如, s t r 1 = a b c str1=“abc” s t r 2 = a d c str2=“adc” i c = 5 ic=5 d c = 3 dc=3 r c = 100 rc=100 。先删除 b b ,再插入 d d 是代价最小的,所以返回 8 8

详细的说明都在注释里面了

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1005;

int m, n;
char str1[N], str2[N];
int ic, dc, rc; //插入、删除、替换的代价 
int dp[N][N]; //dp[i][j]:把 str1[1..i] 编辑成 str2[1..j] 的代价 

int main(void)
{
	cin >> str1 + 1 >> str2 + 1;
	cin >> ic >> dc >> rc;
	m = strlen(str1 + 1), n = strlen(str2 + 1);
	
	//第一列,将 str1[1..i] 编辑为空串 str2
	for (int i = 0; i <= m; i++)
		dp[i][0] = i * dc;
	//第一行,将空串 str1 编辑为 str2[1..j] 
	for (int j = 0; j <= n; j++)
		dp[0][j] = j * ic;
	
	int minv; 
	for (int i = 1; i <= m; i++){
		for (int j = 1; j <= n; j++){
			//1、dc+dp[i-1][j]:先删除字符 str1[i],再将 str1[1..i-1] 编辑为 str2[1..j]
			//2、dp[i][j-1]+ic:先将 str1[1..i] 编辑为 str2[1..j-1],再在末尾插入字符 str2[j] 
			minv = min(dc + dp[i - 1][j], dp[i][j - 1] + ic);
			//3、先将 str1[1..i-1] 编辑为 str2[1..j-1],再将字符 str1[i] 替换为字符 str2[i] 
			if (str1[i] != str2[i])
				minv = min(minv, dp[i - 1][j - 1] + rc);
			//4、将 str1[1..i-1] 编辑为 str2[1..j-1]
			else
				minv = min(minv, dp[i - 1][j - 1]);
			
			dp[i][j] = minv;
		}
	}
	
	cout << dp[m][n] << endl;
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43772166/article/details/106628961