最小编辑代价 动态规划

来源:互联网 发布:1962年中印战争知乎 编辑:程序博客网 时间:2024/06/15 16:37

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];elsedp[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;}

原创粉丝点击