五大常用算法(二) 动态规划算法
一、算法定义
假设当你正在使用适当的输入数据进行一些计算。你在每个实例中都进行了一些计算,以便得到一些结果。当你提供相同的输入时,你不知道会有相同的输出,这就导致了你之前计算某些结果的宝贵时间被浪费掉了。你可以通过保存之前的计算结果去轻易地解决这个问题。比如通过使用恰当的数据结构等。
现在通过分析这个问题,我们可以将新的输入(或者不在数据结构中的输入)与其对应的输出存储下来。或者在字典中查找输入并返回相应的输出结果。这样当你进行一些计算时,你可以检查数据结构中是否存在该输入,如果数据输入存在的话就可以直接获得结果,我们将与这种方法相关的技巧称作 动态规划 。
二、详解动态规划
简而言之,我们可以说动态规划主要用来解决一些希望找到问题最优解的优化问题。
一种可以用动态规划解决的情况就是会有反复出现的子问题,然后这些子问题还会包含更小的子问题。相比于不断尝试去解决这些反复出现的子问题,动态规划会尝试一次解决更小的子问题。之后我们可以将结果输出记录在表格中,我们在之后的计算中可以把这些记录作为问题的原始解。
举个例子,如斐波那契数列0,1,1,2,3,5,8,13,…有着一个相当简单的描述方式,它的每个数字都与前两个紧邻的数字相关。如果 F(n) 是第 n 个数字,那么我们会有 F(n) = F(n-1) + F(n-2)。这个在数学上称作*递归方程*或者*递推关系*。为了计算后面的项,它需要前面项的计算结果作为输入。可参考本人随笔:https://www.cnblogs.com/john1015/p/12909898.html
大多数动态规划问题都能被归类成两种类型:
- 优化问题
优化问题是希望你选择一个可行的解决方案,以便最小化或最大化所需函数的值。
- 组合问题
组合问题是希望你弄清楚做某事方案的数量或某些事件发生的概率。
解决方案的对比:自上而下 或者 自下而上,
以下是两种不同的动态规划解决方案:
- 自下而上:你从最顶端开始不断地分解问题,直到你看到问题已经分解到最小并已得到解决,之后只用返回保存的答案即可。这叫做记忆存储(*Memoization*)。
- 自下而上:你可以直接开始解决较小的子问题,从而获得最好的解决方案。在此过程中,你需要保证在解决问题之前先解决子问题。这可以称为表格填充算法(*Tabulation,*table-filling algorithm**)。
至于迭代和递归与这两种方法的关系,自下而上用到了迭代技术,而自上而下用到了 递归技术。
使用递归算法计算斐波那契数列之所以慢,是因为它重复的计算了相同的数据。
三、应用例子
本人随笔《剑指offer 变态跳台阶》:https://www.cnblogs.com/john1015/p/12916468.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具