什么是动态规划?(完结篇)

简介: 什么是动态规划?(完结篇)

微信图片_20220421114238.jpg在第二集的末尾,给出了一道动态规划的进阶题目——国王和金矿。让我们先来回顾一下问题:


有一个国家发现了5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人数也不同。参与挖矿工人的总数是10人(第二集说的是1000人,这里改动一下)。每座金矿要么全挖,要么不挖,不能派出一半人挖取一半金矿。要求用程序求解出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?


微信图片_20220421114121.jpg



下面,继续我们的故事。


微信图片_20220421114125.jpg微信图片_20220421114127.jpg微信图片_20220421114129.jpg微信图片_20220421114131.jpg

————————————




方法一:排列组合


每一座金矿都有挖与不挖两种选择,如果有N座金矿,排列组合起来就有2^N种选择。对所有可能性做遍历,排除那些使用工人数超过10的选择,在剩下的选择里找出获得金币数最多的选择。


代码比较简单就不展示了,时间复杂度也很明显,就是O(2^N)。


微信图片_20220421114133.jpg微信图片_20220421114135.jpg微信图片_20220421114137.jpg微信图片_20220421114139.jpg微信图片_20220421114141.jpg微信图片_20220421114143.jpg微信图片_20220421114146.jpg微信图片_20220421114148.jpg微信图片_20220421114150.jpg微信图片_20220421114152.jpg微信图片_20220421114154.jpg微信图片_20220421114156.jpg微信图片_20220421114158.jpg微信图片_20220421114203.jpg微信图片_20220421114206.jpg微信图片_20220421114210.jpg微信图片_20220421114212.jpg

微信图片_20220421114215.jpg微信图片_20220421114217.jpg微信图片_20220421114219.jpg微信图片_20220421114221.jpg微信图片_20220421114223.jpg微信图片_20220421114225.jpg



F(n,w) = 0    (n<=1, w<p[0]);


F(n,w) = g[0]     (n==1, w>=p[0]);


F(n,w) = F(n-1,w)    (n>1, w<p[n-1])  


F(n,w) = max(F(n-1,w),  F(n-1,w-p[n-1])+g[n-1])    (n>1, w>=p[n-1])


其中第三条是补充上去的,原因不难理解。

微信图片_20220421114228.jpg微信图片_20220421114230.jpg





方法二:简单递归


把状态转移方程式翻译成递归程序,递归的结束的条件就是方程式当中的边界。因为每个状态有两个最优子结构,所以递归的执行流程类似于一颗高度为N的二叉树。


方法的时间复杂度是O(2^N)。



方法三:备忘录算法


在简单递归的基础上增加一个HashMap备忘录,用来存储中间结果。HashMap的Key是一个包含金矿数N和工人数W的对象,Value是最优选择获得的黄金数。


方法的时间复杂度和空间复杂度相同,都等同于备忘录中不同Key的数量。


微信图片_20220421114235.jpg微信图片_20220421114238.jpg微信图片_20220421114241.jpg微信图片_20220421114244.jpg微信图片_20220421114246.jpg微信图片_20220421114248.jpg微信图片_20220421114251.jpg微信图片_20220421114253.jpg微信图片_20220421114255.jpg微信图片_20220421114258.jpg微信图片_20220421114259.jpg微信图片_20220421114302.jpg微信图片_20220421114304.jpg微信图片_20220421114306.jpg微信图片_20220421114308.jpg微信图片_20220421114310.jpg微信图片_20220421114313.jpg微信图片_20220421114315.jpg微信图片_20220421114318.jpg微信图片_20220421114320.jpg微信图片_20220421114322.jpg微信图片_20220421114325.jpg微信图片_20220421114327.jpg微信图片_20220421114346.jpg微信图片_20220421114348.jpg


方法四:动态规划


微信图片_20220421114351.jpg


方法利用两层迭代,来逐步推导出最终结果。在外层的每一次迭代,也就是对表格每一行的迭代过程中,都会保留上一行的结果数组 preResults,并循环计算当前行的结果数组results。


方法的时间复杂度是 O(n * w),空间复杂度是(w)。需要注意的是,当金矿只有5座的时候,动态规划的性能优势还没有体现出来。当金矿有10座,甚至更多的时候,动态规划就明显具备了优势。



微信图片_20220421114354.jpg微信图片_20220421114356.jpg微信图片_20220421114359.jpg微信图片_20220421114401.jpg微信图片_20220421114404.jpg微信图片_20220421114406.jpg微信图片_20220421114408.jpg微信图片_20220421114411.jpg微信图片_20220421114455.jpg微信图片_20220421114458.jpg微信图片_20220421114500.jpg微信图片_20220421114503.jpg微信图片_20220421114505.jpg微信图片_20220421114507.jpg微信图片_20220421114511.jpg

相关文章
|
算法
【AcWing算法基础课】第五章 动态规划(未完待续)(3)
当然,一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。
107 0
|
4月前
|
算法 开发者 Python
惊呆了!Python算法设计与分析,分治法、贪心、动态规划...这些你都会了吗?不会?那还不快来学!
【7月更文挑战第10天】探索编程巅峰,算法至关重要。Python以其易读性成为学习算法的首选。分治法,如归并排序,将大问题拆解;贪心算法,如找零问题,每步求局部最优;动态规划,如斐波那契数列,利用子问题解。通过示例代码,理解并掌握这些算法,提升编程技能,面对挑战更加从容。动手实践,体验算法的神奇力量吧!
72 8
|
4月前
|
算法 开发者 Python
惊!Python算法界的三大神器:分治法、贪心算法、动态规划,让你秒变算法大师!
【7月更文挑战第8天】在Python编程中,分治、贪心和动态规划是核心算法。分治如归并排序,将大问题拆解并递归求解;贪心算法针对找零问题,每次都选最大面额硬币,追求局部最优;动态规划则通过记忆化避免重复计算,如斐波那契数列。这些算法巧妙地提升效率,解决复杂问题。
44 0
|
6月前
|
算法
贪心算法个人见解
贪心算法个人见解
|
6月前
|
机器学习/深度学习 算法 Java
「程序员必须掌握的算法」动态规划「中篇」
「程序员必须掌握的算法」动态规划「中篇」
|
算法
代码随想录算法训练营第二十九天 | 回溯算法总结
代码随想录算法训练营第二十九天 | 回溯算法总结
50 0
|
算法
代码随想录算法训练营第二十四天 | LeetCode 77.组合
代码随想录算法训练营第二十四天 | LeetCode 77.组合
89 0
一段动态规划代码赏析
输入一个字符串 和 一个pattern. 返回结果是否匹配上
48 0
|
算法 调度
算法基础课第八章动态规划和贪心算法
算法基础课第八章动态规划和贪心算法
111 0
算法基础课第八章动态规划和贪心算法
|
存储 机器学习/深度学习 算法
算法刷题第十二天:动态规划
空间复杂度:O(1)。使用滚动数组,可以只存储前两间房屋的最高总金额,而不需要存储整个数组的结果,因此空间复杂度是O(1)。
112 0
算法刷题第十二天:动态规划