字符串变换最小问题
来源:互联网 发布:法律盈余 知乎 编辑:程序博客网 时间:2024/06/04 23:32
题目:
给出两个字串A,B。将A字串转化为B字串,转化一共有两种方式:删除连续的n个字符,一次操作费用为2。增加连续的n个字符(增加的字符是什么由你决定),一次操作费用为n+2。求把A变为B最小费用。
输入: 第一行输入一个正整数T(1 <= T <= 10),表示有T组测试数据。对于每组测试数据:两行字符串A, B(字符串长度不超过2000,字符仅包含小写字母)输出: 对于每组测试数据,输出一行一个整数,表示最小费用。样例输入: 2dsafsadfadffdfdaaaaaaaabbbbbbbb样例输出: 712答案提示: “dsafsadfadf” 变成 “fdfd” 最少的代价的一种方法是: 1. “dsafsadfadf” -> “f” 删除连续的10个,代价2 2. “f” -> “fdfd” 增加连续的3个(”dfd”),代价为3 + 2 = 5 总共的最小代价为2 + 5 = 7,其他方法的代价都不小于7 “aaaaaaaa” 变成 “bbbbbbbb” 最小代价的一种方法是: 1. “aaaaaaaa” 全部删除,代价2 2. 增加8个连续的’b’,代价10 总共的最小代价为2 + 10 = 12
这是一个比较典型的动态规划的题目:
int compare(const void *a, const void *b){ int *pa = (int*)a; int *pb = (int*)b; return (*pa )- (*pb); //从小到大排序}int DEL = -1;int ORIGAL = 0;int ADD = 1;int getAddCount(int f, int type) { int minCost; if (type == ADD) { minCost = f + 1; } else { minCost = f + 3; } return minCost;}int getDelCount(int f, int type) { int minCost = 0; if (type == DEL) { minCost = f + 0; } else { minCost = f + 2; } return minCost;}int getMin(int a, int b) { return a < b ? a : b;}int getMinExpenses(string aString, string bString) { int **f = new int* [ aString.length() + 1 ] ;//f[i][j] 从a[i] -> b[j]的最小代价 int **oper = new int*[ aString.length() + 1 ];//用于记录操作 for( int i = 0; i < aString.length() + 1; i++ ) { f[i] = new int[ bString.length() + 1 ]; } for( int i = 0; i < aString.length() + 1; i++ ) { oper[i] = new int[ bString.length() + 1 ]; } f[0][0] = 0; for (int i = 1; i < aString.length() + 1; i++) { f[i][0] = 2; oper[i][0] = DEL; } for (int i = 1; i < bString.length() + 1; i++) { f[0][i] = 2 + i; oper[0][i] = ADD; } for (int i = 1; i < aString.length() + 1; i++) { for (int j = 1; j < bString.length() + 1; j++) { int cost = 0; if (aString[i - 1] != bString[j - 1] ) { cost = 5; } int minCost; int delCount = getDelCount(f[i - 1][j], oper[i - 1][j]); int addCount = getAddCount(f[i][j - 1], oper[i][j - 1]); if (delCount >= addCount) { oper[i][j] = ADD; minCost = addCount; } else { oper[i][j] = DEL; minCost = delCount; } if (minCost > f[i - 1][j - 1] + cost) { oper[i][j] = ORIGAL; minCost = f[i - 1][j - 1] + cost; } f[i][j] = minCost; } } return f[aString.length()][bString.length()];}
在做动态规划的题目的时候,需要明白自己需要建几张二维表,以及二维表的实际物理意义。将原文题,递归到子问题。这样可以写出递归方程。
数据结构和递归方程便是程序的两个重要部分。
如代码所示: f[i][j]表示 从a[i] -> b[j]的最小代价,以 “dsafsadfadf” 变成 “fdfd” 为例:
f的数组的内容如下:
operate数组内容如下:
cost=5 为一个常量,含义是由A 到B 如果两个字符不等。那么他所消耗的代价就为5。(删除一个代价为2,增加一个为5) 如果字符相等,那么他的代价就为0.
结合代码 以d到f 为例。有d 到f 有三种路径可以走。
初始条件: 由d到0,消耗的代价为 2 由0到f,消耗的代价为 3
考虑问题的递归性:
1.先删除d,那么需要进行add f 操作,得到 f : 代价为 2+3
2.先增加f,那么需要进行DEL d 操作,得到f: 代价为 3+2
在这两个操作的时候考虑到递推问题的上一个状态,她的前一状态是 DEL,还是ADD
3.第三种状态就是,不管子问题,就是直接删除一个,加一个,为5.
从左到右为 ADD状态,从上到下为DEL状态。ORIGAL,为对角线过来的数据,也就是说,不考虑这个字母的前一个状态。
递归方程如下:
0 0
- 字符串变换最小问题
- 字符串变换最小费用
- 华为校招第三题:字符串变换最小费用(动态规划DP问题)
- 华为oj 字符串变换最小花费
- 字符串最小周期问题
- 最大最小字符串问题
- 字符串最小周期串问题
- 字符串最小周期串问题
- 字符串的最小窗口问题
- 求字符串中变换位置问题
- 字符串变换
- 字符串变换
- 最小表示法 字符串循环同构问题
- 字符串问题---回文最小分割数
- HDU 3746 字符串匹配(字符串的最小循环节问题)
- 字符串问题---数组中两个字符串的最小距离
- 最小字符串
- 最小字符串
- c语言 辗转相除法求最大公约数
- Javascript“预编译”理解
- C#索引器
- 为什么空指针?
- Linux下dpkg的用法
- 字符串变换最小问题
- win10操作系统下重启电脑java环境变量失效
- 将ceph与calamari相连(connect ceph servers to calamari)
- 回文的判断
- keras安装opencv
- cookie、sessionStorage和localStorage的区别
- 链表 C++
- 判断闰年 输出闰年
- grep命令与egrep命令详解