【进击的算法】基础算法——动态规划

news2024/11/16 1:42:52

在这里插入图片描述

🍿本文主题:动态规划
🎈更多算法:回溯算法
💕我的主页:蓝色学者的主页

文章目录

  • 一、前言
  • 二、概念
    • 2.1概念一:状态转移
    • 2.2概念二:Dp数组
  • 三、例题
    • 3.1斐波那契数列
      • 3.1.1题目描述
      • 3.1.2状态转移
      • 3.1.3Dp数组
        • Dp数组优化:
      • 参考代码
    • 3.2爬楼梯
      • 3.2.1 题目描述
      • 3.2.2状态转移
      • 3.2.3Dp数组
      • 参考代码
  • 四、作业
  • 五、结语

一、前言

很开心又和大家见面了,今天我们来一起学习一下传说中的动态规划,通过两道很经典的动态规划题目,帮助大家快速的理解动态规划的思想(斐波那契数列、爬楼梯),之后我还会留下本节课的作业,感兴趣的话一起来看看吧~

二、概念

动态规划(Dynamic Programming)是运筹学的一个分支,是求解决策过程最优化的过程。在初次见到动态规划的题目时,我们会听到诸如:状态转移方程、Dp数组等概念,我们就从这些概念入手,揭开动态规划的神秘面纱~

2.1概念一:状态转移

何为状态转移呢?我想让你思考一个问题:

求4!= ?
注:[n!]指的是n的阶乘,例如 3!= 3 * 2 * 1

根据阶乘的定义,我们想到 4!= 4 * 3 * 2 * 1 = 24
再仔细观察一下,就会得出 4!= 4 * 3!

这样我们得出了一个结论:

要求[n]的阶乘,只需要求出[n-1]的阶乘,要求[n-1]的阶乘,只需要求出[n-2]的阶乘

这样我们就完成了一次状态转移,即:要求[n]的值,先去求[n-1]的值

2.2概念二:Dp数组

理解了状态转移,我们再来看看Dp数组是什么,同样的,我们再思考一个问题:

为什么要有Dp数组?

不妨再去思考一下上面阶乘的问题,如果要求[4!],我们需要什么呢?
要求[4!]——需要先求[3!]
要求[3!]——需要先求[2!]
要求[2!]——需要先求[1!]

假如没有一个Dp数组,我们将之前的阶乘结果放到哪里去呢!
在计算 [4!] 的时候,希望能够直接拿到 [3!],因此我们必须要把 [3!] 实现存入一个数组。

我们把这种存放前面状态的数组,叫做Dp数组,正是有这种数组帮助,我们才能省去很多繁琐的重复计算

三、例题

3.1斐波那契数列

3.1.1题目描述

题目链接:剑指offer-斐波那契数列
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。

斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

3.1.2状态转移

根据本题对斐波那契数列的定义,我们知道第n项等于第n-1项加上第n-2项,与状态转移概念相符,因此本题我们可以使用动态规划来求解。
在这里插入图片描述

3.1.3Dp数组

要求第n个斐波那契数,就要求第n-1个和第n-2的斐波那契数,因此我们的Dp数组就应该存放斐波那契数,注意,由于Dp(0)、Dp(1)没有前两个斐波那契数,因此我们要对这两个元素提前赋值。

Dp[0] = 0;
Dp[1] = 1;

Dp数组优化:

仔细观察状态转移,我们会发现与阶乘还不同的是,斐波那契数只依赖于前两个斐波那契数,因此我们可以将Dp数组优化成两个变量。

注:两者本质上都是动态规划的思路

参考代码

纯动态规划代码:

int fib(int n)
{
    if(n == 0) return 0;
    if(n == 1) return 1;
    int Dp[n+1];
    Dp[0] = 0;
    Dp[1] = 1;
    for(int i = 2;i<=n;i++)
        Dp[i] = (Dp[i-1] + Dp[i-2]) % 1000000007;
    return Dp[n];
}

Dp数组优化代码:

int fib(int n)
{
    if(n == 0) return 0;
    if(n == 1) return 1;
    int F1 = 0;
    int F2 = 1;
    int F3 = F1 + F2;
    for(int i = 2;i<n;i++)
    {
        F1 = F2;
        F2 = F3;
        F3 = (F1 + F2)%1000000007;
    }
    return F3;
}

3.2爬楼梯

3.2.1 题目描述

题目链接:leetcode70 爬楼梯
假设你正在爬楼梯。需要 [n] 阶你才能到达楼顶。
每次你可以爬 [1] 或 [2] 个台阶。你有多少种不同的方法可以爬到楼顶呢?

3.2.2状态转移

根据题目要求,要爬到第n楼,有两种方法,也就是从[n-1]楼爬1步或者从[n-2]楼爬两步,我们肯定不是从底层直接到[n-1]、[n-2]楼的,那么这个问题就转换成了有多少种方法到[n-1]+有多少方法到[n-2]的一个问题了,这样我们就完成了状态转移的分析

3.2.3Dp数组

要求到第[n]楼要爬多少台阶,Dp数组就是存放要爬多少台阶的数组,由于第一楼、第二楼没有前两楼,我们需要对其初始化:

Dp[1] = 1;
Dp[2] = 1;

参考代码

int climbStairs(int n){
    //dp数组,记录 有几种方法爬到第 n 阶段
    if(n == 1) return 1;
    if(n == 2) return 2;
    int* dp = (int*)malloc(sizeof(int)*(n+1));
    dp[1] = 1;
    dp[2] = 2;
    for(int i = 3;i<=n;i++)
    {
        dp[i] = dp[i-2] + dp[i-1];
    }

    int methed = dp[n];
    return methed;
}

四、作业

分析完两道很经典的动态规划的例题,相信你一定对动态规划有了初步的了解,可以通过下面两道题巩固知识

如果你还想练习一道基础题目:使用最小花费爬楼梯
如果你要挑战稍难一点的题目:不同路径

五、结语

如果你感觉有所收获,可以点赞 + 收藏 +关注 支持一下学者哦~ 我们下次见~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176210.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JQUERY总结(四)

对象拷贝&#xff1a; <script src"jQuery.min.js"></script> <script>$(function(){// var targetObj{};// var obj{// id:0,// name:"xinyi",// location:"henan"// };// //覆盖以前的相同key值对应的数据// $.…

【自然语言处理】基于NLP的电影评论情感分析模型比较

基于NLP的电影评论情感分析模型比较一段时间以来&#xff0c;使用机器学习的 NLP 任务借助 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;模型被认为是当前的黄金标准。这些模型通常用于我们日常的许多语言处理任务&#xff0c;比如谷…

Java面试题,线程安全问题

线程安全问题一、对线程安全的理解&#xff08;实际上是内存安全&#xff09;二、Thread类的继承、Runable接口的重写三、守护线程四、ThreadLocal原理和使用场景五、sleep、wait、join、yield六、线程池、解释线程池参数一、对线程安全的理解&#xff08;实际上是内存安全&…

JVM面试一

5. JVM 5.1 JVM包含哪几部分? 参考答案 JVM 主要由四大部分组成:ClassLoader(类加载器),Runtime Data Area(运行时数据区,内存分区),Execution Engine(执行引擎),Native Interface(本地库接口),下图可以大致描述 JVM 的结构。 JVM 是执行 Java 程序的虚拟计算…

【计算机组成原理】第一章 计算机系统概述

文章目录第一章 知识体系1.1 计算机发展历程1.1.1 计算机硬件的发展1.1.2 计算机软件的发展1.2 计算机系统层次结构1.2.1 计算机系统的组成1.2.2 计算机硬件1.2.3 计算机软件1.2.4 计算机的层次结构1.2.5 计算机系统的工作原理1.3 计算机的性能指标第一章 知识体系 1.1 计算机发…

35.Isaac教程--机械臂取放物体示例应用程序

机械臂取放物体示例应用程序 ISAAC教程合集地址文章目录机械臂取放物体示例应用程序使用 Omniverse 套件模拟驱动的机器人手臂启动取放示例应用程序该包为拾取和放置场景提供了一个应用程序脚手架。 它具有执行拾取和放置任务所需的高级步骤&#xff0c;并与两种类型的机器人操…

Java面试题,Spring与SpringBoot相关问题

Spring与SpringBoot相关问题1、BeanFactory和ApplicationContext有什么区别&#xff1f;2、描述一下Spring Bean的生命周期3、Spring的几种Bean的作用域4、单例Bean是线程安全的吗&#xff1f;5、Spring框架用到了哪些设计模式6、Spring事务的实现方式、隔离级别、传播行为7、S…

Lesson4--栈和队列

目录 1.栈 1.1栈的概念及结构 1.2栈的实现 初始化栈 销毁栈 栈的扩容 入栈 出栈 获取栈顶元素 获取栈中有效元素个数 判空 程序代码如下 Stack.h Stack.c test.c 2.队列 2.1队列的概念及结构 ​2.2队列的实现 初始化队列 队尾入队列 队头出队列 获取队列头部元素 获取…

二、pyhon基础语法篇(黑马程序猿-python学习记录)

黑马程序猿的python学习视频&#xff1a;https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 一 、print 1. end 2. \t对齐 二、字面量 1. 字面量的含义 2. 常见的字面量类型 3. 如何基于print语句完成各类字面量的输出 三、 注释的分类 1. 单行注释 2. 多行注释 3. 注释的…

多进程|基于非阻塞调用的轮询检测方案|进程等待|重新理解挂起|Linux OS

说在前面 今天给大家带来操作系统中进程等待的概念&#xff0c;我们学习的操作系统是Linux操作系统。 我们今天主要的目标就是认识wait和waitpid这两个系统调用。 前言 那么这里博主先安利一下一些干货满满的专栏啦&#xff01; 手撕数据结构https://blog.csdn.net/yu_cbl…

nacos源码分析==服务订阅-服务端推送被订阅者最新信息给订阅者

上一篇讲到客户端发送请求到服务端进行服务注册&#xff0c;注册后&#xff0c;服务端会发出两个事件&#xff0c;第一个事件会触发另一个ServiceChangedEvent&#xff0c;这个事件被com.alibaba.nacos.naming.push.v2.NamingSubscriberServiceV2Impl#onEvent 监听&#xff0c…

16. 条件控制

总体来说&#xff0c;条件控制的效果类似c/c/c#/java中的&#xff0c;只不过在语法格式的层面上存在一定的差异。 1. if条件语法格式 if condition_1:...elif condition_2:...else:...1、python 中用 elif 代替了 c/c中的 else if&#xff0c;所以if语句的关键字为&#xff1a…

高性能排序函数实现方案

如C语言的qsort()、Java的Collections.sort()&#xff0c;这些排序函数如何实现&#xff1f; 1 合适的排序算法&#xff1f; 线性排序算法的时间复杂度较低&#xff0c;适用场景特殊&#xff0c;通用排序函数不能选择。 小规模数据排序&#xff0c;可选时间复杂度O(n^2)算法大…

【算法】滑动窗口

目录1.概述2.算法框架3.应用本文参考&#xff1a; LABULADONG 的算法网站 1.概述 &#xff08;1&#xff09;滑动窗口可以用以解决数组/字符串的子元素相关问题&#xff0c;并且可以将嵌套的循环问题&#xff0c;转换为单循环问题&#xff0c;从而降低时间复杂度。故滑动窗口算…

【数据分析】(task5)数据建模及模型评估

note 文章目录note一、建立模型二、模型评估2.1 交叉验证2.2 混淆矩阵/recall/accuracy/F12.3 ROC曲线三、Pyspark进行基础模型预测时间安排Reference一、建立模型 下载sklearn的命令pip install scikit-learn。 from sklearn.model_selection import train_test_split impor…

ARP渗透与攻防(二)之断网攻击

ARP断网攻击 系列文章 ARP渗透与攻防(一)之ARP原理 1.环境准备 kali 作为ARP攻击机&#xff0c;IP地址&#xff1a;192.168.110.26 MAC地址&#xff1a;00:0c:29:fc:66:46 win10 作为被攻击方&#xff0c;IP地址&#xff1a;192.168.110.12 MAC地址&#xff1a;1c:69:7a:a…

Tkinter的Entry与Text

Tkinter界面设计之输入控件Entry以及文本框控件Text。 目录 一、放置控件 1. pack()函数 2. place()函数 3. grid()函数 二、简单控件 1. Entry输入控件 1.1 tk.StringVar()函数&#xff1a;接收一个字符串 1.2 tk.Entry()函数&#xff1a;设置一个输入控件E 2. Text文…

CMake多文件编译

之前学习ceres-solver中的3d相关的源码的时候&#xff0c;发现对于CMake多文件工程编译中对于CMakeLists.txt的编写和处理的理解运用还是比较模糊&#xff0c;这里整理梳理一下对于不同文件夹数量如何使用。 参考文章&#xff1a; CMake使用详解二&#xff08;多文件编译&…

maya常用操作

1&#xff1a;重置工作区。2&#xff1a;切换视图。按空格切换视图。3&#xff1a;未选中状态&#xff0c;按shift&#xff0c;再点右键&#xff0c;可以打开交互式创建。这样可以在栅格上创建想要的大小。不选中交互式创建的话&#xff0c;创建的是默认未知。默认未知为正中间…

linux系统中利用QT实现车牌识别的方法

大家好&#xff0c;今天主要和大家分享一下&#xff0c;如何利用QT实现车牌识别的方法。 目录 第一&#xff1a;车牌识别基本简介 第二&#xff1a;车牌识别产品申请 第三&#xff1a;百度车牌识别API接口 第四&#xff1a;车牌识别综合测试 第一&#xff1a;车牌识别基本简…