动态规划的基本思想
将一个问题划分为多个不独立的子问题,这些子问题在求解过程中可能会有些数据进行了重复计算。我们可以把计算过的数据保存起来,当下次遇到同样的数据计算时,就可以查表直接得到答案,而不是再次计算
动态规划的例子
找两个字符串匹配的编辑距离
字符串的编辑距离,又称为Levenshtein距离,是指利用字符操作,把字符串A转换成字符串B所需要的最少操作数。操作包括增删改
**问题:**给定两个字符串A:sun和B:sautr,求字符串A至少经过多少步字符操作变成字符串B
解:
用<i,j>表示字符串A长为i,字符串B长为j的字符串编辑距离
对两个字符串,最末位字符进行讨论
相同:那么末位字符不需要进行操作,那么<i,j>=<i-1,j-1>
不相同:
可以做三种操作:
Ⅰ:增加一个字符:
增加后,末尾字符相同,问题变成i+1长的字符串A与j长的字符串B匹配
<i,j>=<i+1,j>+1,+1是此次做的增加操作
又由上可知<i,j>=<i-1,j-1>,所以
<i,j>=<i,j-1>+1
Ⅱ:删
同理,<i,j>=<i-1,j>+1
Ⅲ:改
同理,<i,j>=<i-1,j-1>+1
做矩阵图,<i,j>框内数字表示A前i个字符与B前j个字符匹配时,最小修改次数,由图可知,确定它的最小值,如果末尾字符相同,则等于左侧对角线值,不相等,则从周围三个数值中,选最小的+1
背包问题
**问题:**有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?
假设现在有四个物品,背包容量为8
i(编号) 1 2 3 4
w(体积) 2 3 4 5
v(价值) 3 4 5 6
解:
矩阵图中<i,j>表示从下标为 [0 - i] 的物品里任意取,放进容量为j的背包,价值总和最大是多少。
每次我们有两种选择:
将物品放入背包:加该物品的重量和价值
不放入:保持原来的数值
如果容量为3,可以选择的物品有1,2,3
那么我们只需要比较<i-1,j>,<i-1,j-w(i))>+v(i)
其中<i-1,j>表示不装该物品,<i-1,j-w(i))>+v(i) 表示装了该商品,背包容量减少w(i),但价值增加了v(i);
取两者中最大值即可