最小编辑代价 动态规划

这篇博客探讨了如何利用动态规划算法解决最小编辑代价问题。内容包括题目描述、输入输出示例以及详细的解题思路。作者指出,关键在于定义状态dp[i][j]表示将str1的前i位编辑成str2的前j位的最小代价,并列举了三种状态转移情况:替换、删除和插入。最后给出了实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、题目描述:来源于《算法与数据结构题目最优解》左程云著

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


2、输入

abc

adc

5 3 2

abc

adc

5 3 100

abc

abc

5 3 2

ab12cd3

abcdf

5 3 2


3、输出

2

8

0

8


4、题目解析

1)题目的关键还是在于找状态,这个题目的状态dp[i][j]就代表用str1的前 i 位 编辑成 str2 的前 j 位的最小代价。

2)关键点之二在于初始状态的时候,字符串的初始状态一般是空字符串,这样考虑起来就比较容易了,我一开始是从第一个字符开始的,其实也可以,不过不如空串直观。

3)关键点之三在于状态的迭代,这个的情况比较多,想从str1的前 i 个得到 str2的前 j 个,

a、可以是前 i-1 个组成了 前 j-1 个,这样就用str1第 i 个 替换成str2的第 j 个就行了,不过如果str1[i]==str2[j], 就不用替换了(我就没考虑到这种情况);

b、可以是前 i-1个组成了前 j 个,那么只需要删除第 i 个

c、可以是前 i 个组成了前 j-1 个,那么只需要再插入一个。


5、代码如下:

#include<iostream>
#include<vector>
#include<string>

using namespace std;
int getMin(int, int);
int main() {
	string str1, str2;
	int ic, dc, rc;//插入、删除、替换
	int len1, len2;
	int i, j;
	getline(cin, str1);
	getline(cin, str2);
	cin >> ic >> dc >> rc;
	len1 = str1.length();
	len2 = str2.length();
	vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1));//dp[i][j]代表用去str1的前i为变成str2的前j位的最小代价,并且初始化从空字符串开始
	//下面对dp进行赋值,从dp[0][0]代表空字符串
	dp[0][0] = 0;
	for (i = 1; i < len1 + 1; ++i) {
		dp[i][0] = dp[i - 1][0] + dc;
	}
	for (j = 1; j < len2 + 1; ++j) {
		dp[0][j] = dp[0][j - 1] + ic;
	}
	for (i = 1; i < len1 + 1; ++i) {
		for (j = 1; j < len2 + 1; ++j) {
			if (str1[i] == str2[j])//一定要注意考虑str1[i]是否和str2[j]相等
				dp[i][j] = dp[i - 1][j - 1];
			else
				dp[i][j] = dp[i - 1][j - 1] + rc;
			dp[i][j] = getMin(dp[i][j],dp[i][j-1]+ic);
			dp[i][j] = getMin(dp[i][j], dp[i - 1][j] + dc);
		}
	}
	cout << "the minimum value is: " << dp[len1][len2] << endl;
}
int getMin(int v1, int v2) {
	if (v2 < v1)return v2;
	return v1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值