动态规划是一种解决棘手问题的方法,它将问题分成小问题,并先着手解决这些小问题
一、背包问题:一个背包的容量是4磅,吉他容量一磅,价值1500美元,音响容量4磅,价值3000美元,笔记本电脑容量3磅,价值2000美元,问题:如何是背包里面装的东西价值最高
物品/容量 | 1 | 2 | 3 | 4 |
吉他 | 1500 | 1500 | 1500 | 1500 |
音响 | 1500 | 1500 | 1500 | 3000 |
笔记本电脑 | 1500 | 1500 | 2000 | 3500 |
如上图,表格最开始时,里面的金额是空的,需要从第一行往下一行一行填充
1)吉他行,第一个单元格表示背包的容量是一磅,吉他重量也是一磅,可以放入背包,价值1500,第一行的第二个表格,这是第一行,只有吉他可以选择,所以也是1500美元,第三第四类似
2)音响行,在第二行时,背包可以放入吉他和音响了,第二行的第一个表格,只可以放入一磅的,所以还是吉他,价值1500美元,第二第三类似,第四个表格时,可以放入音响,所以是3000美元
4)笔记本电脑行,第一第二表格只能放入吉他,都是1500,第三个表格时,容量是3磅,可以放入笔记本电脑,所以是2000,第四个表格时,当前四磅的最大价值是3000美元,当时你可以选择拿笔记本电脑,是2000美元,现在还剩一磅的容量,而一磅容量最大的价值是1500美元,所以第三行第四格的最大价值是3500美元。
每个表格的技术公式如下: cell[i][j] = 上一个单元格的价值(即 cell[i-1][j]的值)或者当前商品的价值 + 剩余空间的价值 (cell[i-1][j-d-当前商品的重量]) 这两者中较大的那个
当增加一行时,比如iPhone的价值是2000美元,重量是1磅时,单元格如下:
物品/容量 | 1 | 2 | 3 | 4 |
吉他 | 1500 | 1500 | 1500 | 1500 |
音响 | 1500 | 1500 | 1500 | 3000 |
笔记本电脑 | 1500 | 1500 | 2000 | 3500 |
ipone | 2000 | 3500 | 3500 | 4000 |
一、最大的价值随着行数增大而增大
二、行的排列顺序发生变化时,结果不会改变
三、增加一个容量更小的商品时,列数会考虑更细的粒度,而增加列数
动态规划能够解决子问题并使用这些答案来解决大问题,但仅当每个子问题都是离散的,即不依赖于其他子问题时,动态规划才管用。
最长公共子串问题:找出两个单词的最长公共子串。比如hish和fish都包含的最长子串是什么,hish和vista呢
字母 | h | i | s | h |
f | 0 | 0 | 0 | 0 |
i | 0 | 1 | 0 | 0 |
s | 0 | 0 | 2 | 0 |
h | 1 | 0 | 0 | 3 |
字母 | V | I | S | T | A |
H | 0 | 0 | 0 | 0 | 0 |
I | O | 1 | 0 | 0 | 0 |
S | 0 | 0 | 2 | 0 | 0 |
H | 0 | 0 | 0 | 0 | 0 |
单元格填充值公式: 1)如果两个字母不相同,值为0, 2)如果两个字母相同,值为左上角邻居的值加1
最长公共子序列的解决方案:如何找出两个单词中都有的序列包含的字母数。比如:fosh和fish两个单词中包含有多少个公共的字母数是多少个。
字母 | F | O | S | H |
F | 1 | 1 | 1 | 1 |
O | 1 | 2 | 2 | 2 |
R | 1 | 2 | 2 | 2 |
T | 1 | 2 | 2 | 2 |
最长公共子序列是2
单元格填充公式: 1) 如果两个字母不同,就选择上方和左方邻居中较大的那个 2)如果两个字母相同,就将当前单元格的值设置为左上方单元格的值加1
动态规划的例子:
一,生物学家根据最长公共序列来确认DNA链的相似性,进而判断两种动物或疾病有多相似。最长公共序列还被用来寻找多发性硬化症治疗方案。
二,我们使用的git diff命令,来指出两个文件的差异,也是使用动态规划实现的。
三,前面讨论的字符串相似程度,编辑距离指出了两个字符串的相似程度,也是使用动态规划计算得到的,编辑距离算法的用途很多,从拼写检查到判断用户上传的资料是否是盗版,都有用到
四,我们使用的WORD等具有断字功能的应用程序,当如何判断在什么地方断字以确保行长一致,使用的也是动态规划。
费曼算法:
一、将问题写下来
二、好好思考
三、将答案写下来