Python之动态规划

news2025/1/11 14:01:19

序言

最近在学习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))

在这里插入图片描述

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

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

相关文章

上滑动导航栏手势桌面最近任务可见解密-千里马手把手带你搞定framework车载车机系统开发

建议先看另一篇blog&#xff1a; https://blog.csdn.net/learnframework/article/details/123032419 系统如何让桌面执行对应的onStart方法呢&#xff1f; 具体的堆栈显示如下&#xff1a; makeActiveIfNeeded:5788, ActivityRecord (com.android.server.wm) makeVisibleIfNe…

MOS管开关电路栅极为什么要串接电阻

在MOS管开关电路或者驱动电路中&#xff0c;常常会在MOS管的栅极串接一个电阻。 这个电阻阻值一般是几十欧姆&#xff0c;那么这个电阻有什么作用呢&#xff1f; 第一个作用就是可以限制驱动电流 &#xff0c;防止瞬间驱动电流过大导致驱动芯片驱动能力不足或者损坏。 MOS管的…

CANOCO5.0实现冗余分析(RDA)最详细步骤

在地理及生态领域会常使用RDA分析&#xff0c;RDA的实现路径也有很多&#xff0c;今天介绍一下CANOCO软件的实现方法。 1.软件安装 时间调整到2010年 2.数据处理 得有不同的物种或者样点数值&#xff0c;再加上环境因子数据。 3.软件运行 4.结果解读 结果解读主要把握这几点…

1、[春秋云镜]CVE-2022-32991

文章目录 一、相关信息二、解题思路&#xff08;手注&#xff09;三、通关思路&#xff08;sqlmap&#xff09; 一、相关信息 靶场提示&#xff1a;该CMS的welcome.php中存在SQL注入攻击。 NVD关于漏洞的描述&#xff1a; 注入点不仅在eid处&#xff01;&#xff01;&#xff…

加油站【贪心算法】

加油站 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 gas 和…

Stable Diffusion Web UI的原理与使用

Stable Diffusion是一套基于Diffusion扩散模型生成技术的图片生成方案&#xff0c;随着技术的不断发展以及工业界对这套工程细节的不断优化&#xff0c;使其终于能在个人电脑上运行&#xff0c;本文将从github下载开始讲一讲如何使用Stable Diffusion Web UI进行AI图像的生成。…

el-table 单击某一行,该行的前面的多选框显示已勾选

目 录 官网&#xff1a; 1. 单页面 2. table是组件 案例&#xff1a; 官网&#xff1a; 1. 单页面 通过单击获取当前行的数据&#xff0c;然后传给选中显示勾选的方法。 <template><el-tableref"multipleTable":data"tableData"tooltip-eff…

matlab使用教程(28)—微分方程(ODE)求解常见问题

1.非负 ODE 解 本博客说明如何将 ODE 解约束为非负解。施加非负约束不一定总是可有可无&#xff0c;在某些情况下&#xff0c;由于方程的物理解释或解性质的原因&#xff0c;可能有必要施加非负约束。仅在必要时对解施加此约束&#xff0c;例如不这样做积分就会失败或者解将不…

Unity Canvas动画不显示的问题

问题描述: 我通过角色创建了一个walk的动画&#xff0c;当我把这个动画给到Canvas里面的一个image上&#xff0c;这个动画就不能正常播放了&#xff0c;经过一系列的查看我才发现&#xff0c;canvas里面动画播放和非canvas得动画播放&#xff0c;他们的动画参数是不一样的。一个…

微服务--服务介绍

1.2.2 常见微服务架构 1. dubbo: zookeeper dubbo SpringMVC/SpringBoot 配套 通信方式: rpc 注册中心: zookeeper/redis 配置中心: diamond 2.SpringCloud: 全家桶轻松入第三方组件(Netflix) 配套 通信方式: http restful 注册中心: eruka /consul 配置中心: config 断 路器…

【学习笔记】计算机视觉对比学习综述

计算机视觉对比学习综述 前言百花齐放InstDiscInvaSpreadCPCCMC CV双雄MoCoSimCLRMoCo v2SimCLR v2SwAV 不用负样本BYOLSimSiam TransformerMoCo v3DINO 总结参考链接 前言 本篇对比学习综述内容来自于沐神对比学习串讲视频以及其中所提到的论文和博客&#xff0c;对应的链接详…

Linux学习之权限

在学习Linux权限之前&#xff0c;我们先理解一下关于Linux内核与shell外壳之间的关系&#xff1a; shell命令以及运行原理 Linux严格意义上说的是一个操作系统&#xff0c;我们称之为“核心&#xff08;kernel&#xff09;“ &#xff0c;但我们一般用户&#xff0c;不能直接使…

Redis笔记——(狂神说)

Nosql概述 为什么要用NoSql&#xff1f; 1、单机mysql的年代&#xff1a;90年代&#xff0c;网站访问量小&#xff0c;很多使用静态网页html写的&#xff0c;服务器没压力。 当时瓶颈是&#xff1a;1)数据量太大一个机器放不下。2)数据的索引(BTree)&#xff0c;一个机器内存也…

Kotlin判断null比较let布尔值Boolean

Kotlin判断null比较let布尔值Boolean class MyData {val count: Int? 2023val number: Int? null }fun main(args: Array<String>) {val data MyData()val year 2022if (data.count ! null) {if (data.count > year) {println("data.count ! null")}}…

【STM32】学习笔记(OLED)-江科大

调试方式 OLED简介 硬件电路 驱动函数 OLED.H #ifndef __OLED_H #define __OLED_Hvoid OLED_Init(void); void OLED_Clear(void); void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char); void OLED_ShowString(uint8_t Line, uint8_t Column, char *String); void OL…

项目进度与实施计划汇报实践样例模板

一、IT项目实施步骤 项目启动 项目启动 项目启动 项 项目启动 | 需求调研 | 解决方案设计与系统实现 | UAT测试与培训 | 上线与运维支持

【LeetCode题目详解】第八章 贪心算法 part05 435. 无重叠区间 763.划分字母区间 56. 合并区间 (day36补)

本文章代码以c为例&#xff01; 一、力扣第435题&#xff1a;无重叠区间 题目&#xff1a; 给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 示例 1: 输入: intervals [[1,…

SpringMVC-学习笔记

文章目录 1.概述1.1 SpringMVC快速入门 2. 请求2.1 加载控制2.2 请求的映射路径2.3 get和post请求发送2.4 五种请求参数种类2.5 传递JSON数据2.6 日期类型参数传递 3.响应3.1 响应格式 4.REST风格4.1 介绍4.2 RESTful快速入门4.3 简化操作 1.概述 SpringMVC是一个基于Java的Web…

day-04 基于UDP的服务器端/客户端

一.理解UDP &#xff08;一&#xff09;UDP套接字的特点 UDP套接字具有以下特点&#xff1a; 无连接性&#xff1a;UDP是一种无连接的协议&#xff0c;这意味着在发送数据之前&#xff0c;不需要在发送方和接收方之间建立连接。每个UDP数据包都是独立的&#xff0c;它们可以独…