动态规划(一)
2016-02-29 13:23
309 查看
基本概念
在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分程若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又印象以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线,这种把一个问题看作是一个前后关联具有连庄结果的多阶段过程就称为多阶段决策过程,这种问题就称为多阶段决策问题。动态规划过程:每次决策依赖于当前状态,又随即引起状态的转义。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就成为动态规划。
举例(一)
《算法导论》上面第一个讲解的动态规划问题就是Rod-Cutting 问题Input: 有一个长n米的木头,和一个price table如下:
长度 i | 1 | 2 | 3 | 4 | 5 | 6 |
价格P[i] | 1 | 5 | 8 | 9 | 10 | 17 |
递归解法
最简单的方法,遍历假设P[i]代表长度为i的木头的价格,max_price代表最大的价格, x 代表一次切的米数
那么,如下递归肯定成立
def cut(table, l): q = 0 if l <= 0: return 0 # i 表示一次切的米数 for i in table.keys(): q = max(q, table[i] + cut(table, l - i)) return q
这是一个简单的递归,但是计算的重复度非常高,计算了大量的重复数据,经过我测试,就算l = 15
这个重复的数字都能让人做恶梦,重复了92167次
所以这只是一个暴力递归的解法
动态规划
回过头来,我们发现,cut(table, l - i)调用的次数太多了,我们完全可以建立一张表,来记录所有的max(q, table[i] + cut(table, l - i)) 这样,很多值就不用重新计算了,这就是动态规划的思路代码如下:
def cut_dp(table, l): r = [0] * (l + 1) for i in range(1, l + 1): q = 0 for j in table.keys(): q = max(q, table[j] + r[i - j]) r[i] = q return r[l]
跟非动态规划的算法其实比较一致,只不过是计算时,将每次计算的最大值都记录到了表r中,这样就大大降低了迭代的次数。
相关文章推荐
- 动态规划(一)
- python学习(1)启程
- Android学习笔记之View(一):LayoutInflater
- Android学习笔记之View(二)
- Array中对象的排序
- 项目经理之项目经理的基本特征
- cassandra介绍
- windows下cocos2dx3.4中打包apk的方法
- 插入排序算法分析
- Android Activity学习 <二> Activity间通讯
- UIViewAlertForUnsatisfiableConstraints
- Android开发之如何监听让Service不被杀死
- RxJava 过滤操作符 ofType
- 1001. A+B Format
- 小米手机与魅族的PK战结果 说明了什么
- Fragment使用
- 乱码问题的解决
- C++调试时的错误例子及解决方法
- 103.Daikon Forge高级控件checkbox、dropdownlist、listbox、progressbar
- A Simple Math Problem