通过例子说明-动态规划

选择>行动>思考,好像是个死循环 -song。

 动态规划(Dynamic Programming,简称DP)是一种解决问题的数学优化方法,通常用于解决具有重叠子问题和最优子结构性质的问题。它的基本思想是将问题拆分成小的子问题,先求解并保存子问题的解,然后通过这些子问题的解来求解原始问题,避免重复计算,从而提高效率。

 最常见的动态规划问题包括最长公共子序列、最短路径、背包问题等。让我们通过一个简单的例子来理解动态规划:

 

例子:斐波那契数列

斐波那契数列是一个经典的动态规划问题。数列的定义是:F(0) = 0,F(1) = 1,F(n) = F(n-1) + F(n-2)(n ≥ 2)。

现在我们想要计算第 n 个斐波那契数,如果直接按照递归定义来计算,会存在大量的重复计算,效率很低。而动态规划的思想是从底向上逐步计算,并保存中间结果。

def fibonacci(n):
    if n <= 1:
        return n

    # 初始化一个数组来保存中间结果
    dp = [0] * (n + 1)
    dp[1] = 1

    # 从底向上逐步计算
    for i in range(2, n + 1):
        dp[i] = dp[i - 1] + dp[i - 2]

    return dp[n]

# 测试
print(fibonacci(5))  # 输出 5

在这个例子中,通过动态规划的方式,我们避免了重复计算,将问题拆解成小的子问题,从而高效地计算出了斐波那契数列的第 n 项。这是动态规划的基本思想,通过保存中间结果,避免重复计算,提高算法效率。

这里可能还有很多朋友不懂,咱们继续通俗一点的说:

当我们解决问题时,有时候问题很大,我们会把它分成一些小问题,解决小问题的过程中,我们会保存一些信息,以便后面解决更大的问题。动态规划就是这样一种策略。

比如,我们想算斐波那契数列的第 n 项,斐波那契数列的规律是:第一个数字是0,第二个数字是1,后面的数字是前两个数字的和。数列的前几项是 0, 1, 1, 2, 3, 5, 8, 13, ... 。

现在,我们要算第 n 项,如果直接算可能会很慢,因为要重复计算很多次相同的数字。动态规划就是为了避免这种重复计算。

我们可以这样做:

  1. 从小问题开始,先算出前两个数字(0和1)。
  2. 把这两个数字存下来。
  3. 然后,计算第三个数字,它是前两个数字的和。存下来。
  4. 依次类推,计算第四个、第五个,一直到第 n 个数字。

在这个过程中,我们不是每次都从头算,而是用之前算过的结果,这样就避免了大量的重复计算。

简而言之,动态规划就是将一个大问题拆成一系列小问题,逐步解决这些小问题,并且把中间结果保存下来,避免重复计算,最终得到整个问题的解。

让我们用一个更简单的例子来解释动态规划:

问题:爬楼梯

假设你要爬一个楼梯,每次你只能迈一步或两步。问:爬到楼梯顶端有多少种不同的方式?

现在,我们可以使用动态规划来解决这个问题。

  1. 定义子问题: 要爬到第 n 级楼梯,我们可以从第 n-1 级走一步,或者从第 n-2 级走两步。

  2. 找出状态转移方程:dp[i] 表示爬到第 i 级楼梯的不同方式数,那么 dp[i] = dp[i-1] + dp[i-2]

  3. 初始化: 对于前两级楼梯,有 dp[0] = 1(不需要爬),dp[1] = 1(一种方式,爬一步)。

  4. 递推: 从第三级楼梯开始,使用状态转移方程逐步计算 dp[2]dp[3],一直到 dp[n]

  5. 返回结果: 最终结果是 dp[n],表示爬到楼梯顶端的不同方式数。

看看这个通俗易懂的 Python 代码:

def climbStairs(n):
    # 初始化
    dp = [0] * (n + 1)
    dp[0] = 1
    dp[1] = 1

    # 递推
    for i in range(2, n + 1):
        dp[i] = dp[i - 1] + dp[i - 2]

    # 返回结果
    return dp[n]

# 测试
result = climbStairs(4)
print(result)  # 输出 5

这里的 dp[4] 就表示爬到第四级楼梯的不同方式数,结果是5。这个例子简单明了,但也展示了动态规划的基本思想:将大问题拆解成小问题,通过保存中间结果避免重复计算,从而高效解决问题。

再讲一个例子:

想象你站在一个楼梯底部,目标是爬到楼梯顶端。你每次可以迈一步或者迈两步。问题是:爬到楼梯顶端,有多少不同的方式?

解释:

  1. 第一步: 如果楼梯只有一级,你只有一种方式,就是迈一步就到了。

  2. 第二步: 如果楼梯有两级,你可以选择迈一步两次或者一次迈两步。所以,有两种方式。

  3. 第三步: 如果楼梯有三级,你可以从第一级迈两步,也可以从第二级迈一步。这样就把问题拆分成了前两级楼梯的问题。

  4. 第四步: 如果楼梯有四级,你可以从第三级迈一步,也可以从第二级迈两步。同样,这又把问题拆分成了前两级楼梯的问题。

这个过程可以一直持续下去。而这就是动态规划的思想:

  • 拆分问题: 将大问题拆分成小问题,先解决小问题的答案。

  • 保存中间结果: 为了避免反复计算,我们保存每一步的答案。

通过这种方式,你可以从楼梯底部一步一步地找到爬到楼梯顶端的不同方式数。

在代码中,我们用一个列表(dp)来保存每一级楼梯的不同方式数。通过迭代计算,最终得到了爬到楼梯顶端的答案。

问题:买糖果

假设你去糖果店,你有一些零钱,而糖果有不同的价格。现在,你想知道用你的零钱有多少种方式可以买到糖果。

  1. 定义小问题: 想象你有一些零钱,要买到一块钱的糖果,有几种方式?要买到两块钱的糖果,有几种方式?

  2. 找出规律: 如果你知道了买到一块钱和两块钱的方式,你就能推导出买到三块钱的方式。因为可以从买到两块钱的情况下再加一个硬币,或者从买到一块钱的情况下再加两个硬币。

  3. 定义状态转移方程:dp[i] 表示用你的零钱买到 i 块钱糖果的不同方式数。那么 dp[i] = dp[i-1] + dp[i-2] + ...

  4. 初始化: 对于买到一块钱的糖果,有 dp[1] = 1 种方式(就是用一块钱买一个)。对于买到两块钱的糖果,有 dp[2] = 2 种方式(可以用两个一块的或一个两块的)。

  5. 递推: 从买到三块钱的情况开始,一直递推到你想知道的金额。

  6. 返回结果: 最终结果是 dp[你的零钱],表示用你的零钱能够购买到糖果的不同方式数。

这个问题和前面爬楼梯的问题类似,只是现在我们在考虑的是零钱和糖果的价钱。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

革新性技术:基于搜索操作的存内计算

文章目录 革新性技术&#xff1a;基于搜索操作的存内计算CSDN首个存内计算开发者社区NVALT&#xff1a;近似查找表的艺术MAP&#xff1a;存内计算的未来SQL-PIM&#xff1a;数据库的未来内存计算架构与技术小结从NVALT到NVQuery&#xff1a;存内计算的探索与前景NVQuery&#x…

242. 有效的字母异位词(力扣)(C语言题解)

✨欢迎来到脑子不好的小菜鸟的文章✨ &#x1f388;创作不易&#xff0c;麻烦点点赞哦&#x1f388; 所属专栏&#xff1a;刷题 我的主页&#xff1a;脑子不好的小菜鸟 文章特点&#xff1a;关键点和步骤讲解放在 代码相应位置 题目链接&#xff1a; 242. 有效的字母异位词 …

UE5 C++ 读取本地图片并赋值到UI上

目录 结果图 节点样式 主要代码 调试代码 结果图 节点样式 主要代码 &#xff08;注释纯属个人理解&#xff0c;可能存在错误&#xff09; // Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h&q…

Mysql进阶篇

1.Mysql服务架构 连接层: 处理客户端连接请求,对用户进行认证 服务层: 可以接收sql,调用存储过程,优化sql,缓存数据.... 引擎层: 负责实际与文件层进行交互操作的,可以有不同的引擎选择. 物理文件层: 存储表数据 以及 各种日志文件. 2.Mysql引擎 存储引擎就是存储数据&…

TSINGSEE青犀视频智慧电梯管理平台,执行精准管理、提升乘梯安全

一、方案背景 随着城市化进程的不断加快&#xff0c;我国已经成为全球最大的电梯生产和消费市场&#xff0c;电梯也成为人们日常生活中不可或缺的一部分。随着电梯数量的激增&#xff0c;电梯老龄化&#xff0c;维保数据不透明&#xff0c;物业管理成本高&#xff0c;政府监管…

StarRocks-3.1.0 单节点部署

1. 相关环境准备 FE&#xff1a; /opt/starrocks BE&#xff1a; /opt/starrocks 安装包下载 wget https://releases.starrocks.io/starrocks/StarRocks-3.1.0.tar.gz解压缩 tar -zxvf StarRocks-3.1.0.tar.gz 安装jdk (v2.5 及以上版本建议安装 JDK 11&#xff0c;我们使用…

腾讯mini项目总结-指标监控服务重构

项目概述 本项目的背景是&#xff0c;当前企业内部使用的指标监控服务的方案的成本很高&#xff0c;无法符合用户的需求&#xff0c;于是需要调研并对比测试市面上比较热门的几款开源的监控方案&#xff08;选择了通用的OpenTelemetry协议&#xff1a;Signoz&#xff0c;otel-…

MedSAM:深度学习通用医学影像分割模型,更快、更准确地自动识别诊断疾病

MedSAM是一款基于深度学习的医学影像分割工具&#xff0c;它能够自动识别和描绘医学影像中的重要区域&#xff0c;如肿瘤或其他组织的病变。该工具通过学习大量医学影像和对应的掩模&#xff08;即正确的分割结果&#xff09;&#xff0c;能够处理各种不同的医学影像和复杂情况…

数据库之TiDB基础讲解

文章目录 1 TiDB1.1 引言1.2 TiDB介绍1.3 系统架构1.3.1 TIDB Server1.3.2 PD Server1.3.3 TIKV Server1.3.4 TiKV如何不丢失数据1.3.5 分布式事务支持 1.4 与MySQL的对比1.5 性能测试1.5.1 测试一1.5.2 系统测试报告 2 1 TiDB 1.1 引言 当我们使用 Mysql 数据库到达一定量级…

使用nginx对视频、音频、图片等静态资源网址,加token签权

目前很多静态资源&#xff0c;都可以无权限验证&#xff0c;进行访问或转发&#xff0c;对有价值的资源进行签权&#xff0c;限制转发无法在代码中实现拦截&#xff0c;我们可以使用nginx对视频、音频、图片等静态资源网址&#xff0c;加token签权 如&#xff1a; http://192…

Win10 双网卡实现同时上内外网

因为需要同时上内网和外网&#xff0c;但公司做了网络隔离&#xff0c;不能同时上内外网&#xff0c;所以多加了块无线网卡&#xff0c;配置双网关实现同时上内外网&#xff0c;互不影响 打开 Windows PowerShell&#xff08;管理员&#xff09;&#xff0c;输入&#xff1a;ro…

CCF-CSP 202312-2 因子化简(Java、C++、Python)

文章目录 因子化简题目背景问题描述输入格式输出格式样例输入样例输出样例解释子任务 满分代码JavaCPython线性筛法 因子化简 题目背景 质数&#xff08;又称“素数”&#xff09;是指在大于 1 的自然数中&#xff0c;除了 1 和它本身以外不再有其他因数的自然数。 问题描述…

房屋租赁系统-java

思维导图&#xff1a;业务逻辑 类的存放&#xff1a; 工具类 Utility package study.houserent.util; import java.util.*; /***/ public class Utility {//静态属性。。。private static Scanner scanner new Scanner(System.in);/*** 功能&#xff1a;读取键盘输入的一个菜单…

DevOps落地笔记-02|影响地图:产品规划和需求分析的利器

从这一讲开始&#xff0c;我们进入 DevOps 正题。按照端到端的顺序&#xff0c;讲解 DevOps 中的最佳实践如何在软件开发过程中发挥作用。所谓端到端&#xff0c;是指从需求提出到需求被发布到生产环境交付给用户的整个过程&#xff0c;可以理解为软件开发的全生命周期。所谓最…

06 SB3之Thymeleaf实现视图返回

1快速尝试一个返回视图的项目 1.1创建器添加Web, Thymeleaf, lombok依赖创建项目 1.2 编写Controller Controller public class QuickController {RequestMapping("/exam/quick") public String quick(Model model){//业务处理结果数据&#xff0c;放入到 Model 模…

【lesson1】高并发内存池项目介绍

文章目录 这个项目做的是什么&#xff1f;这个项目的要求的知识储备和难度&#xff1f;什么是内存池池化技术内存池内存池主要解决的问题malloc 这个项目做的是什么&#xff1f; 当前项目是实现一个高并发的内存池&#xff0c;他的原型是google的一个开源项目tcmalloc&#xf…

万户 ezOFFICE SendFileCheckTemplateEdit.jsp SQL注入漏洞

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日…

Redis内存设置

通过redis-cli进入Redis命令行 redis权限认证命令&#xff1a;auth 查看redis内存使用情况的命令&#xff1a;info memory 查看最大内存命令&#xff1a;config get maxmemory 设置最大内存命令&#xff1a;config set maxmemory 也可以通过redis.conf配置文件修改最大内存…

MicroPython核心:映射和字典

MicroPython字典和映射使用称为开放寻址和线性探测的技术&#xff0c;本文详细介绍了这两种方法。 开放寻址 开放寻址用于解决碰撞问题&#xff0c;碰撞是非常常见的现象&#xff0c;当两个条目恰好散列到同一个槽或位置时就会发生碰撞。例如&#xff0c;散列设置如下&#x…

计算机基础知识讲解(原码反码补码)(以及在C语言里面是如何计算和运用的)

补码反码掩码以及原理 补码、反码和掩码是计算机科学中用于表示和处理数值的三种编码方式。 原码 原码是最直观的数值表示方法&#xff0c;它将数值的二进制表示与其符号位结合起来。在原码表示中&#xff0c;正数的符号位为0&#xff0c;而负数的符号位为1。原码的缺点在于…