Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >动态规划入门

动态规划入门

作者头像
uniartisan
发布于 2022-03-02 11:37:55
发布于 2022-03-02 11:37:55
46300
代码可运行
举报
文章被收录于专栏:uu的自留地uu的自留地
运行总次数:0
代码可运行

五大常用算法: 动态规划

引入

1. 基本概念

动态规划英文 Dynamic Programming,是求解决策过程最优化的数学方法,后来沿用到了编程领域。

动态规划的大致思路是把一个复杂的问题转化成一个分阶段逐步递推的过程,从简单的初始状态一步一步递推,最终得到复杂问题的最优解。

动态规划解决问题的过程分为两步:

  • 寻找状态转移方程
  • 利用状态转移方程式自底向上求解问题

找出来以下三点,题目就完成了80%:

  • 状态表示:如何用数组表示实际问题
  • 状态转移:如何由已知状态表示未知状态
  • 状态边界:哪些状态不用转移就可以得到

具有以下三个特性的问题适用于动态规划:

  • 最优子结构:全局最优解包含局部最优解
  • 重叠子问题:子问题出现大量重叠
  • 无后效性:每次决策不影响之后的决策

2. 爬楼梯问题

题目描述:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数。

简化题目:

假设这里只有十级台阶,方便于表述。

动态规划思路:

动态规划简单来说就是:大事化小,小事化了。

那这道题目来讲,假设还差最后一步走到第十级台阶,这时候有两种情况:还有 1 级台阶/ 2级台阶。 如果暂时不考虑 08 级的过程,也不管 09 级的过程,那么 0~10级的走法就是这两个方法的数值之和。

这时我们不考虑总共的台阶为 10,换为 8/9,我们重新考虑分别走到第八级和第九级的方法。这里我们先假设走到第 N 级台阶的方法为 F(N): F(10)=F(8)+F(9)

同理:

F(9)=F(8)+F(7)

F(8)=F(7)+F(6)

此时: F(N)=F(N-1)+F(N-2) 是阶段与阶段之间的 状态转移方程

递归实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int getNumWays(int n)        \\二叉树
{
    if (n < 1) {
        return 0;
    }
    if (n == 1) {
        return 1;
    }
    if (n == 2) {
        return 2;
    }
    else {
        return getNumWays(n - 1) + getNumWays(n - 2);
    }
}
备忘录算法

上面的算法时间复杂度很高,树的结点个数是递归的计算次数。树的高度为 N-1,节点个数接近 2^n-1,时间复杂度为 O(2^n)。

如果用树状图来表示的话,我们可以得到一颗二叉树:

可以看到,重复计算了很多相同的参数输入。我们可以通过数组或者哈希表记录节点值来完成时间复杂度的简化。 这里我们用c++中STL来实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
map <int, int> cache;
int getNumWays(int n)
{
    if (n < 1) {
        return 0;
    }
    if (n == 1) {
        return 1;
    }
    if (n == 2) {
        return 2;
    }
    if (cache.count(n)) {
        return cache[n];
    }
    else {
        int value = getNumWays(n - 1) + getNumWays(n - 2);
        cache[n] = value;
        return value;
    }
}

在以上代码中,集合 cache 是一个备忘录。当每次需要计算F(N)的时候,会首先从 cache 中寻找匹配元素。如果存在,就直接返回结果,如果不存在,就计算出结果,存入备忘录中。 可以简单得到,这个算法复杂度为 O(N)。

动态规划

虽然到上面一步已经实现了时间复杂度的优化,但还算不上真正的动态规划。 前面提到:

动态规划解决问题的过程分为两步:

  • 寻找状态转移方程
  • 利用状态转移方程式自底向上求解问题

我们继续尝试自下而上迭代计算结果,由于每一次步的结果只依赖于之前的两个状态,所以我们只用推导新的状态。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int getNumWays(int n)
{
    if (n < 1) {
        return 0;
    }
    if (n == 1) {
        return 1;
    }
    if (n == 2) {
        return 2;
    }
    int a = 1, b = 2, temp = 0;

    for (int i = 3; i <= n; i++) {
        temp = a + b;
        a = b;
        b = temp;
    }

    return temp;
}

程序从 i=3 开始迭代,一直到 i=n 结束。每一次迭代,都会计算出多一级台阶的走法数量。迭代过程中只需保留两个临时变量a和b,分别代表了上一次和上上次迭代的结果。 为了便于理解,我引入了temp变量。temp代表了当前迭代的结果值。

基本思想

基本思想是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。

总结

在利用动态规划求解问题的过程中,比较难的是找到状态转移方程,当前项和前两项的关系。 当然例题也只是最简单的动态规划,是一道板子题。

找到这种关系后,需要转化思路,自底向上编写程序,这样才能降低时间复杂度。

>动态规划剖析

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
动态规划快速入门
动态规划算法一直是面试手撕算法中比较有挑战的一种类型。很多的分配问题或者调度问题实际上都可能用动态规划进行解决。(当然,如果问题的规模较大,有时候会抽象模型使用动归来解决,有时候则可以通过不断迭代的概率算法解决查找次优解)
全菜工程师小辉
2019/08/16
5020
一文说清动态规划
动态规划(dynamic programming,简称 dp)是工程中非常重要的解决问题的思想,从我们在工程中地图软件上应用的最短路径问题,再在生活中的在淘宝上如何凑单以便利用满减券来最大程度地达到我们合理薅羊毛的目的 ,很多时候都能看到它的身影。不过动态规划对初学者来说确实比较难,dp状态,状态转移方程让人摸不着头脑,网上很多人也反馈不太好学。其实任何算法的学习都是有它的规律和套路的,只要掌握好它的规律及解题的套路,再加上大量的习题练习,相信掌握它不是什么难事。本文将会用比较浅显易懂地讲解来帮助大家掌握动态规划这一在工程中非常重要的思想,相信看完后,动态规划的解题套路一定能手到擒来(文章有点长,建议先收藏再看,看完后一定会对动态规划的认知上升到一个台阶!)
Crossin先生
2020/02/25
8190
一文学会动态规划解题技巧
动态规划(dynamic programming,简称 dp)是工程中非常重要的解决问题的思想,从我们在工程中地图软件上应用的最短路径问题,再在生活中的在淘宝上如何凑单以便利用满减券来最大程度地达到我们合理薅羊毛的目的 ,很多时候都能看到它的身影。不过动态规划对初学者来说确实比较难,dp状态,状态转移方程让人摸不着头脑,网上很多人也反馈不太好学,其实就像我们之前学递归那样,任何算法的学习都是有它的规律和套路的,只要掌握好它的规律及解题的套路,再加上大量的习题练习,相信掌握它不是什么难事,本文将会用比较浅显易懂地讲解来帮助大家掌握动态规划这一在工程中非常重要的思想,相信看完后,动态规划的解题套路一定能手到擒来(文章有点长,建议先收藏再看,看完后一定会对动态规划的认知上升到一个台阶!)
乔戈里
2020/02/24
6700
一文学会动态规划解题技巧
看一遍就理解:动态规划详解
我们刷leetcode的时候,经常会遇到动态规划类型题目。动态规划问题非常非常经典,也很有技巧性,一般大厂都非常喜欢问。今天跟大家一起来学习动态规划的套路,文章如果有不正确的地方,欢迎大家指出哈,感谢感谢~
捡田螺的小男孩
2021/04/23
6180
看一遍就理解:动态规划详解
动态规划之武林秘籍
听到 动态规划 这个响亮的大名你可能已经望而却步,那是因为这个响亮的名字真的真的很具有迷惑性,不像递归、回溯和贪心等等算法一样,其文即其意,而动态规划则不同,很容易望文生义,真可谓害人不浅,今天我就带大家一起扒一扒 动态规划 的裤子。
灵魂画师牧码
2020/11/06
9070
动态规划之武林秘籍
动态规划详解
动态规划算法(Dynamic Programming,简称 DP)似乎是一种很高深莫测的算法,你会在一些面试或算法书籍的高级技巧部分看到相关内容,什么状态转移方程,重叠子问题,最优子结构等高大上的词汇也可能让你望而却步。
帅地
2019/07/01
3.5K3
动态规划详解
动态规划详解(修订版)
这篇文章是我们号半年前一篇 200 多赞赏的成名之作 动态规划详解 的进阶版。由于账号迁移的原因,旧文无法被搜索到,所以我润色了本文,并添加了更多干货内容,希望本文成为解决动态规划的一部「指导方针」。
labuladong
2021/09/23
6320
漫画说算法|动态规划解决扔鸡蛋问题
动态规划英文 Dynamic Programming,是求解决策过程最优化的数学方法,后来沿用到了编程领域。
小白学视觉
2019/07/09
6510
漫画说算法|动态规划解决扔鸡蛋问题
八十八、从斐波那契数列和零一背包问题探究动态规划
本人看了vivo,阿里巴巴的校招算法题,可以明确知道绝对有动态规划。如果没有,那么出题的面试官真的没有水平。跌了N次的动态规划,Runsen最近也拼命搞动态规划。这篇文章浪费了三天时间。
润森
2022/08/17
4550
八十八、从斐波那契数列和零一背包问题探究动态规划
算法之动态规划
动态规划(Dynamic Programming,简称DP)算法是一种通过将问题(比较复杂)划分为相互重叠的子问题(简单易于求解),并解决子问题来解决原问题的方法。它通常用于优化问题,其中需要找到最优解或最大/最小值。
九转成圣
2024/04/10
1950
算法之动态规划
动态规划算法
对于一个具有n个输入的最优化问题,其求解过程往往可以划分为若干个阶段,每一阶段的决策依赖于前一阶段的状态,由决策所采取的动作使状态发生转移,成为下一阶段决策的依据。从而,一个决策序列在不断变化的状态中产生。这个决策序列产生的过程称为多阶段决策过程。
WHYBIGDATA
2023/01/31
4150
动态规划算法
一文带你入门动态规划
我们首先明确一点,动态规划问题的一般形式就是求最大值或者最小值。 其核心就是穷举。因为求最值肯定要将其全部的可能都列出来,这才找的出最值。 动态规划适合的穷举具有重叠子问题的特征,如果暴力穷举,效率回极其低下,所以需要备忘录或则DB table来优化穷举过程,避免不必要的计算。 动态规划问题一定具备最优子结构性质,这样才可以通过子问题得到原问题的解。 动态规划问题的核心是就是穷举出最值,但是问题可以千变万化,穷举出所有可行解并不是 容易的事情,只有列出正确的动态转移方程,才可以正确的穷举。写出动态转移方程也是最难的。 **
一只胡说八道的猴子
2021/04/02
4970
漫画:什么是动态规划?(整合版)
有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶。要求用程序来求出一共有多少种走法。
小灰
2022/07/05
3310
漫画:什么是动态规划?(整合版)
什么是动态规划
招聘结束,结合笔试题给大家分享一下动态规划,LZ最近在GitHub上分享了2个项目一个用是netty实现http服务,还有就是RPC框架Thrift的使用,点下面原文链接即可跳到LZ的GitHub,每个项目的思路都写了博客详细介绍,感兴趣的小伙伴可以给LZ发merge request
Java识堂
2019/08/13
4180
巧解动态规划问题
前言:最近在力扣刷题,但是之前从没有接触过算法题,有的看答案都看不懂,后来做的题做多了发现有好多类似的题目,所以我打算总结一下规律。
wsuo
2020/07/31
8190
巧解动态规划问题
五大常用算法之二:动态规划算法
动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。
全栈程序员站长
2022/07/15
1910
算法学习笔记——动态规划法
动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这样的多阶段最优化决策解决这个问题的过程就称为动态规划。
全栈程序员站长
2022/07/07
3450
动态规划理论学习
一个n乘以n的矩阵w[n][n]。存储的都是正整数。棋子起始位置在左上角,终止位置在右下角。每次只能向右或者向下移动一位。把每条路径经过的数字加起来看作路径的长度。最短路径长度是多少?
Michael阿明
2021/02/20
3460
动态规划理论学习
javascript分类刷leetcode动态规划篇
动态规划,英文:Dynamic Programming,简称DP,将问题分解为互相重叠的子问题,通过反复求解子问题来解决原问题就是动态规划,如果某一问题有很多重叠子问题,使用动态规划来解是比较有效的。
hellocoder2028
2022/12/09
3310
看动画轻松理解「递归」与「动态规划」
在学习「数据结构和算法」的过程中,因为人习惯了平铺直叙的思维方式,所以「递归」与「动态规划」这种带循环概念(绕来绕去)的往往是相对比较难以理解的两个抽象知识点。
五分钟学算法
2019/01/02
9210
相关推荐
动态规划快速入门
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验