Python之动态规划

序言

最近在学习python语言,语言有通用性,此文记录复习动态规划并练习python语言。

动态规划(Dynamic Programming)

动态规划是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题、最短路径问题和复杂系统可靠性问题等中取得了显著的效果。

基本思想:将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。

斐波那契数列(Fibonacci sequence)

斐波那契数列,又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34……在数学上,这一数列以如下递推的方法定义:F(0)=1,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。

先以斐波那契数列为例,了解动态规划。

def fibonacci(num):
    if num == 0:
        return 1
    if num == 1:
        return 1
    return fibonacci(num - 1) + fibonacci(num - 2)


if __name__ == "__main__":
    print(fibonacci(10))

在这里插入图片描述
上述是以递归的方式实现的,然而递归方式存在以下几个缺点:

  • 1)递归调用,占用空间大;
  • 2)递归太深,容易发生栈溢出;
  • 3)可能存在大量重复计算;
结果(n-1)项(n-2)项
f(n)f(n-1)f(n-2)
f(5)f(4)f(3)
f(4)f(3)f(2)
f(3)f(2)f(1)
f(2)f(1)f(0)

以上述表格为例,可以看到在求下一个递归结果时,计算了之前已经计算出来的结果,存在重复计算项。

如果采用动态规划的方式,那么可以节省计算,采用数组暂存之前已经计算出来的结果。如下,

def fibonacci_dp(num):
    # 定义一个数组暂存dp结果,数组初始值为-1
    dp = [-1] * (num + 1)
    dp[0] = 1
    dp[1] = 1
    for i in range(2, num + 1):
        dp[i] = dp[i - 1] + dp[i - 2]
    return dp[num]


if __name__ == "__main__":
    print(fibonacci_dp(10))

在这里插入图片描述

不同路径

上面的斐波那契数列是一维数组,较为简单,下面以二维数组为例。

题目描述

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?在这里插入图片描述

示例1: 输入:m = 3, n = 7 输出:28

示例2: 输入:m = 3, n = 2 输出:3
解释: 从左上角开始,总共有 3 条路径可以到达右下角。
1.向右 -> 向下 -> 向下
2.向下 -> 向下 -> 向右
3.向下 -> 向右 -> 向下
示例3:
输入:m = 7, n = 3 输出:28
示例4:
输入:m = 3, n = 3 输出:6
1 <= m, n <= 100
题目数据保证答案小于等于 2 * 10^9

python代码

class UniquePaths(object):
    def uniquePaths(self, m: int, n: int) -> int:
        """
        :type m: int
        :type n: int
        :rtype: int
        """

        # 初始化一个二维数组
        dp = [[0] * n for _ in range(m)]
        for i in range(m):
            dp[i][0] = 1
        for j in range(n):
            dp[0][j] = 1
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
        return dp[m - 1][n - 1]


if __name__ == "__main__":
    demo = UniquePaths()
    print(demo.uniquePaths(7, 3))

在这里插入图片描述

最小路径和

题目描述

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:一个机器人每次只能向下或者向右移动一步。

在这里插入图片描述

示例1:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。
示例2:
输入:grid = [[1,2,3],[4,5,6]]
输出:12
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 200
0 <= grid[i][j] <= 100

python代码

class MinPathSum(object):
    def minPathSum(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        row = len(grid)
        column = len(grid[0])
        # 定义dp[i][j]为到(i,j)处的最小路径和
        dp = [[0] * column for _ in range(row)]
        dp[0][0] = grid[0][0]
        # 第0行j列
        for j in range(1, column):
            dp[0][j] = dp[0][j - 1] + grid[0][j]
        # 第i行0列
        for i in range(1, row):
            dp[i][0] = dp[i - 1][0] + grid[i][0]
        # 非第0行或第0列
        for i in range(1, row):
            for j in range(1, column):
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
        return dp[row - 1][column - 1]


if __name__ == "__main__":
    demo = MinPathSum()
    grid = [[1, 3, 1], [1, 5, 1], [4, 2, 1]]
    print(demo.minPathSum(grid))

在这里插入图片描述

零钱兑换

题目描述

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

你可以认为每种硬币的数量是无限的。

示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:
输入:coins = [2], amount = 3
输出:-1
示例 3:
输入:coins = [1], amount = 0
输出:0
提示:
1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 104

python代码

class CoinChange(object):
    def coinChange(self, coins: list[int], amount: int) -> int:
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """

        # 状态转移方程dp(i) = min(dp(i-Cj)) + 1,Cj为货币面值
        """
        i<0  忽略
        i==0 dp[0] = 0
        i==1 dp[1] = min(dp[1-1], dp[1-2], dp[1-5]) + 1 = 1
        i==2 dp[2] = min(dp[2-1], dp[2-2], dp[2-5]) + 1 = 1
        i==3 dp[3] = min(dp[3-1], dp[3-2], dp[3-5]) + 1 = 2
        i==4 dp[4] = min(dp[4-1], dp[4-2], dp[4-5]) + 1 = 2
        ... ...
        """
        dp = [0] * (amount + 1)
        dp[0] = 0
        for i in range(1, amount + 1):
            mini = int(1e9)
            for coin in coins:
                if i >= coin:
                    res = dp[i - coin]
                    if 0 <= res < mini:
                        mini = res
            dp[i] = mini + 1 if mini < int(1e9) else -1
        if amount < 1:
            return 0
        return dp[amount]


if __name__ == "__main__":
    demo = CoinChange()
    coins = [1, 2, 5]
    amount = 11
    print(demo.coinChange(coins, amount))

在这里插入图片描述

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

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

相关文章

【DevOps视频笔记】8. Jenkins 配置

一、Jenkins 入门配置 1. 工具 / 插件 介绍 二、插件和工具配置 1. 配置 JDK 和 Maven Stage 1&#xff1a;将服务器中 JDK 和 Maven 映射到 jenkins 容器中 Stage 2&#xff1a;jenkins 全局配置中 -- 指定JAVA_HOME目录 Stage 3&#xff1a;jenkins 全局配置中 -- 指定…

Vue 项目性能优化 — 实践指南

前言 Vue 框架通过数据双向绑定和虚拟 DOM 技术&#xff0c;帮我们处理了前端开发中最脏最累的 DOM 操作部分&#xff0c; 我们不再需要去考虑如何操作 DOM 以及如何最高效地操作 DOM&#xff1b;但 Vue 项目中仍然存在项目首屏优化、Webpack 编译配置优化等问题&#xff0c;所…

深度图相关评测网站

文章目录 1 单目/Stereo相关测评网站介绍12 单目/Stereo相关测评网站介绍23 单目/Stereo相关测评网站介绍3 1 单目/Stereo相关测评网站介绍1 https://vision.middlebury.edu/stereo/eval3/ 2 单目/Stereo相关测评网站介绍2 http://www.cvlibs.net/datasets/kitti/eval_stereo…

maven推包The environment variable JAVA_HOME is not correctly set

解决办法&#xff1a; 打开idea查看jdk安装位置 1.在/etc下面创建&#xff08;如果存在就是更新&#xff09;launchd.conf。里面添加一行&#xff1a; setenv JAVA_HOME /Library/Java/JavaVirtualMachines/jdk1.8.0_351.jdk/Contents/Home #JAVA_HOME后面是我的java安装路径…

vscode GDB 调试linux内核 head.S

遇到的问题 此前参考如下文章 https://zhuanlan.zhihu.com/p/510289859 已经完成了在ubuntu 虚拟机用vscode 调试linux 内核。但是美中不足的是&#xff0c;断点最早只能加在__primary_switched() 函数。无法停在更早的断点上&#xff0c;比如ENTRY(stext) 位置。参考《奔跑吧…

数据库的备份与分类以及日志

目录 1、数据库的概念 1.1、数据备份的重要性 1.2、造成数据丢失的原因 1.3、 数据库备份的分类 1.3.1、从物理与逻辑的角度&#xff0c; 1.3.2、原理图 1.3.3.1 完全备份&#xff1a; 1.3.2.2 差异备份 1.2.3.3、 增量备份 1.3.3、 备份方式比较 1.4、常见的备份方…

全新抖音快手小红书去水印系统网站源码 | 支持几十种平台

全新抖音快手小红书去水印系统网站源码 | 支持几十种平台

arm版Linux下安装es集群

背景&#xff1a;由于生产上网络没通&#xff0c;没办法&#xff0c;只能自己安装一个es集群的测试环境了&#xff0c;我的电脑是Mac M2&#xff0c;安装的Linux是centos7&#xff0c;也是arm版的。 第一步&#xff1a;查看自己Linux系统的版本 命令&#xff1a;uname -a 例如…

Midjourney学习(二)参数的基础

prompt的组成 prompt 可以由三部分组成&#xff0c; 第一部分是垫图部分&#xff0c;也就是一张网络图片 第二部分是文本描述内容 第三部分则是参数 参数列表 --aspect <value> 或者 --ar <value> 控制画面的比例&#xff0c;横竖比例 --version <value> -…

批量身份证图片转Excel,核验真伪,保留头像,只需一款软件

你是否曾经遇到过需要将大量员工的身份证图片转化为Excel表格的情况&#xff1f;这种情况可能会让你感到无从下手。但是&#xff0c;现在有了金鸣表格文字识别电脑客户端&#xff0c;一切都将变得轻松便捷。 首先&#xff0c;你只需要前往金鸣识别官网下载并安装金鸣表格文字识…

电缆厂 3D 可视化管控系统 | 图扑数字孪生

近年来&#xff0c;我国各类器材制造业已经开始向数字化生产转型&#xff0c;使得生产流程变得更加精准高效。通过应用智能设备、物联网和大数据分析等技术&#xff0c;企业可以更好地监控生产线上的运行和质量情况&#xff0c;及时发现和解决问题&#xff0c;从而提高生产效率…

vue项目静态文件资源下载

业务场景&#xff1a;页面有一个导入功能&#xff0c;需要一个模板文件供下载&#xff0c;文件放在本地。 对于 Vue 3 Vite 项目&#xff0c;使用 require 方法来导入模块是不被支持的。require 是 CommonJS 规范中用于模块导入的方法&#xff0c;在 Webpack 等构建工具中常用…

编绎和优化,脚本代码小米加步枪赶超英法美

编程达人&#xff1a;冰冻牡蛎 测试&#xff0c;总结》》 今有空&#xff0c;继续看了一下竹笋大师几天前提出的“使用for循环查找10亿内可被7整除的数的个数”的题目&#xff08;相关文件&#xff1a;群文件 10亿以内多少个数字可以整除7.7z &#xff09; 1. 论输出的exe大小…

matlab使用教程(27)—微分代数方程(DAE)求解

1.什么是微分代数方程&#xff1f; 微分代数方程是一类微分方程&#xff0c;其中一个或多个因变量导数未出现在方程中。方程中出现的未包含其导数的变量称为代数变量&#xff0c;代数变量的存在意味着您不能将这些方程记为显式形式 y ′ f t , y 。相反&#xff0c;您可以…

Excel:通过Lookup函数提取指定文本关键词

函数公式&#xff1a;LOOKUP(9^9,FIND($G 2 : 2: 2:G 6 , C 2 ) , 6,C2), 6,C2),G 2 : 2: 2:G$6) 公式解释&#xff1a; lookup第一参数为9^9&#xff1a;代表的是一个极大值的数据&#xff0c;查询位置里面最接近这一个值的数据&#xff1b;lookup第二参数用find函数代替&am…

springboot第37集:kafka,mqtt,Netty,nginx,CentOS,Webpack

image.png binzookeeper-server-start.shconfigzookeeper.properties.png image.png image.png 消费 image.png image.png image.png image.png image.png image.png image.png image.png image.png Netty的优点有很多&#xff1a; API使用简单&#xff0c;学习成本低。功能强大…

JUC并发编程--------基础篇

一、多线程的相关知识 栈与栈帧 我们都知道 JVM 中由堆、栈、方法区所组成&#xff0c;其中栈内存是给谁用的呢&#xff1f;其实就是线程&#xff0c;每个线程启动后&#xff0c;虚拟 机就会为其分配一块栈内存。 每个栈由多个栈帧&#xff08;Frame&#xff09;组成&#xf…

Databend 开源周报第 108 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 多源数据目录 …

前端工程化

前后端混合开发 前后端分离开发 接口文档&#xff1a;一个业务功能就是一个接口 开发某个功能的流程&#xff1a; 需求分析&#xff0c;接口定义&#xff08;API接口文档&#xff09;&#xff0c;前后端并行开发&#xff08;遵守规范&#xff09;&#xff0c;测试&#xff…

SpringWeb(SpringMVC)

目录 SpringWeb介绍 搭建 SpringWeb SpringWeb介绍 Spring Web是一个基于 Servlet API 构建的原始 web 框架&#xff0c;用于构建基于MVC模式的Web应用程序。在 web 层框架历经 Strust1&#xff0c;WebWork&#xff0c;Strust2 等诸多产品的历代更选 之后&#xff0c;目前业界普…