​Python—数据结构与算法​---动态规划—DP算法(Dynamic Programing)

article/2025/9/13 8:41:52

我们一路奋战,

不是为了改变世界,

而是为了不让世界改变我们。



目录

我们一路奋战,

不是为了改变世界,

而是为了不让世界改变我们。

动态规划——DP算法(Dynamic Programing)

一、🏔斐波那契数列(递归VS动态规划)

1、🐒斐波那契数列——递归实现(python语言)——自顶向下

2、🐒斐波那契数列——动态规划实现(python语言)——自底向上

二、🏔动态规划算法——思想简介

1、🐒DP算法思想

2、🐒DP算法——解决问题的基本特征

3、🐒DP算法——解决问题的基本步骤

 4、🐒求解例子——求阶乘 n!

三、🏔动态规划——常见例题

1、🐒求解最长不降子序列

2、🐒求解最长的公共子序列

获取源码?私信?关注?点赞?收藏?



动态规划——DP算法(Dynamic Programing)

一、🏔斐波那契数列(递归VS动态规划)

1、🐒斐波那契数列——递归实现(python语言)——自顶向下

递归调用是非常耗费内存的,程序虽然简洁可是算法复杂度为O(2^n),当n很大时,程序运行很慢,甚至内存爆满。

def fib(n):#终止条件,也就是递归出口if n == 0 or n == 1:return 1else:#递归条件return (fib(n-1) + fib(n - 2))

2、🐒斐波那契数列——动态规划实现(python语言)——自底向上

动态规划——将需要重复计算的问题保存起来,不需要下次重新计算。对于斐波那契数列,算法复杂度为O(n)。

def dp_fib(n):#初始化一个数组,用于存储记录计算的结果。res = [None] * (n + 1)#前两项设置为1。res[0] = res[1] = 1#自底向上,将计算结果存入数组内。for i in range(2, (n + 1)):res[i] = res[i-1] + res[i-2]return res[n]

3、🐒方法概要

   (1)构造一个公式,它表示一个问题的解是与它的子问题的解相关的公式:

     

  (2)为这些子问题做索引,以便于它们能够在表中更好的存储与检索(用数组存储)。

  (3)以自底向上的方法来填写这个表格;首先填写最小的子问题的解。

  (4)这就保证了当我们解决一个特殊的子问题时,可以利用比它更小的所有可利用的子问题的解。

总之,因为在上世纪40年代(计算机普及很少时),这些规划设计是与“列表”方法相关的,因此被称为动态规划——Dynamic Programing。


二、🏔动态规划算法——思想简介

1、🐒DP算法思想

   (1)将待求解的问题分解称若干个子问题,并存储子问题的解而避免计算重复的子问题,并由子问题的解得到原问题的解。

   (2)动态规划算法通常用于求解具有某种最有性质的问题。

   (3)动态规划算法的基本要素:最优子结构性质和重叠子问题。

      最优子结构性质:问题的最优解包含着它的子问题的最优解。即不管前面的策略如何,此后的决策必须是基于当前状态(由上一次的决策产生)的最优决策。

      重叠子问题:在用递归算法自顶向下解问题时,每次产生的子问题并不总是新问题,有些问题被反复计算多次。对每个子问题只解一次,然后将其解保存起来,

            以后再遇到同样的问题时就可以直接引用,不必重新求解。

2、🐒DP算法——解决问题的基本特征

   (1)动态规划一般求解最值(最优、最大、最小、最长)问题;

   (2)动态规划解决 的问题一般是离散的,可以分解的(划分阶段的)。

   (3)动态规划结局的问题必须包含最优子结构,即可以有(n-1)的最优推导出n的最优。

3、🐒DP算法——解决问题的基本步骤

   动态规划算法的四个步骤:

    (1)刻画最优解的结构特性。(一维、二维、三维数组);

    (2)递归的定义最优解。(状态转移方程)

    (3)以自底向上的方法来计算最优解。

    (4)从计算得到的解来构造一个最优解。

 4、🐒求解例子——求阶乘 n!

#递归实现求阶乘def multiply(n):if n == 0 or n == 1:return 1return n * multiply(n -1)#动态规划实现求阶乘def dp_multiply(n):temp = [None] * (n + 1)temp[0] = 1temp[1] = 1for i in range(2, n + 1):temp[i] = i * temp[i - 1]return temp[n]


三、🏔动态规划——常见例题

1、🐒求解最长不降子序列

  (1)方法一:普通方法,算法复杂度为O(n^2)。

      假设原始的数列为数组 a

      分析:

        刻画结构特性:用F[ i ] 表示前 i 项最长不下降子序列的长度;

        状态转移方程:如果a [ i ] >=a [ j ],  F[i] = max(F[i], F[j] + 1)  其中,0 <= j < i

        数据存储:自底向上求解最小子结构最优解存入数组

 其中,pre[ i ]表示以元素a [ i ] 为结尾的最长不降序列的前一个元素索引(也就是以a[i]结尾的最长不降序列的倒数第二个元素)。存储这个值是为了方便输出最长的不降序列。

def Longest_Increaseing(a):F = [1] * len(a)pre = [0] * len(a)for i in range(1, len(a)):for j in range(i):if a[i] >= a[j]:F[i] = max(F[i], F[j] + 1)pre[i] = jreturn F, prea = [5,2,8,6,3,6,9,7]F, pre = Longest_Increaseing(a)#这里只是能获得两个数组,其中F[i]的最大值就是最长不降序列的长度。

接下来,输出最长的不降序列的元素值,请看下面的代码:


2、🐒求解最长的公共子序列

 求解最长公共子序列代码如下(python语言):

  import numpy as npdef LCS(str1, str2):#获取两个序列的长度m = len(str1)n = len(str2)#生成一个存储计算子问题的二位矩阵,并将元素初始化为0。#这个矩阵的尺寸比两个序列的尺寸分别大1个单位。#对于这个矩阵,第一行和第一列元素值必然为0。#C[i][j]的含义是:Xi = (x1, x2, x3,..., xi)和Yj = (y1, y2, x3,..., yj)的最长公共子序列C = np.zeros((m+1, n+1), dtype=int)b = np.zeros((m+1, n+1), dtype=int) for i in range(1, m+1):for j in range(1, n+1):#请注意这里为什么是i-1和j-1,因为其实C[1][1]表示的是# 两个序列的首个元素的最长公共子序列,对应的是str1[0]和str2[0]if str1[i-1] == str2[j-1]:C[i][j] = C[i-1][j-1] + 1b[i][j] = 1      #表示对角线方向else:if C[i][j-1] <= C[i-1][j]:b[i][j] = 2     #表示朝上方向else:b[i][j] = 3     #表示朝左方向C[i][j] = max(C[i][j-1], C[i-1][j])return C, btest1 = ['b', 'd','c', 'a', 'b', 'a']test2 = ["a","b","c","b","d","a","b"]a, b = LCS(test2, test1)print(a)
#矩阵a存储的是公共子序列的长度,最大值就是最大公共子序列的长度
[[0 0 0 0 0 0 0]
[0 0 0 0 1 1 1]
[0 1 1 1 1 2 2]
[0 1 1 2 2 2 2]
[0 1 1 2 2 3 3]
[0 1 2 2 2 3 3]
[0 1 2 2 3 3 4]
[0 1 2 2 3 4 4]]print(b)
#这里: 1表示对角线方向、2表示朝上、3表示朝左,主要是为了求具体的子序列用的。
[[0 0 0 0 0 0 0]
[0 2 2 2 1 3 1]
[0 1 3 3 2 1 3]
[0 2 2 1 3 2 2]
[0 1 2 2 2 1 3]
[0 2 1 2 2 2 2]
[0 2 2 2 1 2 1]
[0 1 2 2 2 1 2]]

 接下来是输出最长公共子序列:

 import numpy as npdef LCS(str1, str2):#获取两个序列的长度m = len(str1)n = len(str2)#生成一个存储计算子问题的二位矩阵,并将元素初始化为0。#这个矩阵的尺寸比两个序列的尺寸分别大1个单位。#对于这个矩阵,第一行和第一列元素值必然为0。#C[i][j]的含义是:Xi = (x1, x2, x3,..., xi)和Yj = (y1, y2, x3,..., yj)的最长公共子序列C = np.zeros((m+1, n+1), dtype=int)b = np.zeros((m+1, n+1), dtype=int)for i in range(1, m+1):for j in range(1, n+1):#请注意这里为什么是i-1和j-1,因为其实C[1][1]表示的是# 两个序列的首个元素的最长公共子序列,对应的是str1[0]和str2[0]if str1[i-1] == str2[j-1]:C[i][j] = C[i-1][j-1] + 1b[i][j] = 1      #表示对角线方向else:if C[i][j-1] <= C[i-1][j]:b[i][j] = 2     #表示朝上方向else:b[i][j] = 3     #表示朝左方向C[i][j] = max(C[i][j-1], C[i-1][j])return C, bdef Print_Lcs(b, X, i , j):if i == 0 or j == 0:returnif b[i][j] == 1:Print_Lcs(b, X, i-1, j-1)print(X[i-1])  #为什么是i-1,因为b矩阵的行比X的行长一个单位,而且只输出相等的值,表示公共元素。elif b[i][j] == 2:Print_Lcs(b, X, i-1, j)else:Print_Lcs(b, X, i, j-1)if __name__ == '__main__':test1 = ['b', 'd','c', 'a', 'b', 'a']test2 = ["a","b","c","b","d","a","b"]a, b = LCS(test2, test1)Print_Lcs(b, test2, 7, 6)#输出的结果是:  b、c、b、a  。(请注意这里结果不唯一,因为最长子序列长度为4, 存在三个序列长度为4的子序列)

好了,这篇博客到这就结束了,感谢大家的阅读!

2023年第二十九期,希望得到大家的喜欢🙇‍

也是新的系列,将会持续更新,🙇‍

希望大家有好的意见或者建议,欢迎私信


以上就是本篇文章的全部内容了

 ~ 关注我,点赞博文~ 每天带你涨知识!

1.看到这里了就 [点赞+好评+收藏] 三连 支持下吧,你的「点赞,好评,收藏」是我创作的动力。

2.关注我 ~ 每天带你学习 :各种前端插件、3D炫酷效果、图片展示、文字效果、以及整站模板 、HTML模板 、C++、数据结构、Python程序设计、Java程序设计、爬虫等! 「在这里有好多 开发者,一起探讨 前端 开发 知识,互相学习」!

3.以上内容技术相关问题可以相互学习,可 关 注 ↓公 Z 号 获取更多源码 !
 


获取源码?私信?关注?点赞?收藏?

👍+✏️+⭐️+🙇‍

有需要源码的小伙伴可以 关注下方微信公众号 " Enovo开发工厂 "🙇‍


http://chatgpt.dhexx.cn/article/duNiaCxx.shtml

相关文章

XDOJ(智慧平台)--分配宝藏(用动态规划dp算法解决)(C语言)

------------------------------------------------------------ 作为西电渣渣&#xff0c;这是我第一次接触需要一些很明确的算法的题目。 第一次博客写废话较多hhh&#xff0c;可以直接到下面看分析 我在昨天晚上和舍友一起肝这道题&#xff0c;肝了一个晚上都没有解决&…

dp算法篇Day1

"多希望有人来陪我&#xff0c;度过末日啊~" 讲讲我为什么突然想更新这篇栏目。 想想自己也算 "系统" 接触计算机这个学科也有差不多一年了&#xff0c;回想起当初下定决心要全身心投入到这个专业或者说行业中来&#xff0c;现在到了这样的地步&#xff0c…

第十四周DP算法总结

这周自己主要再看DP算法的博客&#xff0c;感觉DP这一部分内容确实比之前的都要麻烦一些&#xff0c;最后攻克这一部分难题还是挺好的。 这周自己总结了一些题型&#xff0c;以及一些方法思路&#xff0c;最后再把动态规划和之前的分治和贪心做一下比较。下面是详细的总结。 动…

DP算法(Dynamic Programming,俗称动态规划)是最经典算法之一

DP算法&#xff08;Dynamic Programming,俗称动态规划&#xff09;是最经典算法之一.本笔记以耳熟能详的数塔问题为引子,深入讨论01背包的解决方法. 首先,如下图所示,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少&#xff1f; 这个问题,对…

DP算法:动态规划算法

步骤 &#xff08;1&#xff09;确定初始状态 &#xff08;2&#xff09;确定转移矩阵&#xff0c;得到每个阶段的状态&#xff0c;由上一阶段推到出来 &#xff08;3&#xff09;确定边界条件。 例题 蓝桥杯——印章&#xff08;python实现&#xff09; 使用dp记录状态&#x…

动态规划(DP)算法初识

先用大白话来说一下几种经典算法大概的意思&#xff1a; 贪心算法&#xff1a;我就一次机会&#xff0c;为了达到目的&#xff0c;其他的我啥也不考虑回溯算法&#xff1a;我有无数次机会&#xff0c;还能怕我有达不到目的的时候&#xff1f;动态规划算法&#xff1a;我能随意…

常用十大算法_动态规划算法(DP)

动态规划算法&#xff08;DP&#xff09; 高能预警&#xff1a;DP算法不容易理解&#xff0c;需要动脑筋查资料找例题 动态规划算法&#xff08;Dynamic Programming&#xff09;&#xff0c;是将复杂问题拆分成子问题&#xff0c;并在子问题的基础上&#xff0c;求解复杂问题…

动态规划算法(DP)

校招笔试面试前,大家一般都会先去牛客网上刷刷题,《剑指offer》,《leetcode》走起来,然后初次入手,发现很多不会,不会到什么程度呢,连个想法都没有,于是就去讨论区看答案,然后java大神,c++大神会给出花式解答,他们喜欢在答案前加一句,简单的dp算法,递归就可以解决…

【算法笔记】树形DP算法总结详解

0. 定义 树形DP&#xff0c;又称树状DP&#xff0c;即在树上进行的DP&#xff0c;是DP&#xff08;动态规划&#xff09;算法中较为复杂的一种。 1. 基础 令 f [ u ] f[u]~ f[u] 与树上顶点 u u u有关的某些数据&#xff0c;并按照拓扑序&#xff08;从叶子节点向上到根节点…

★动态规划(DP算法)详解

什么是动态规划&#xff1a;动态规划_百度百科 内容太多了不作介绍&#xff0c;重点部分是无后效性&#xff0c;重叠子问题&#xff0c;最优子结构。 问S->P1和S->P2有多少种路径数&#xff0c;毫无疑问可以先从S开始深搜两次&#xff0c;S->P1和S->P2找出所有路…

ubuntu安装qt

Ubuntu安装qt 到qt官网下载“qt-opensource-linux-x64-5.9.1.run” 分别安装g, build-essential, libglq-mesa-dev, libglu1-mesa-dev freeglut3-dev 输入指令&#xff1a;”sudo apt-get install g” -> “sudo apt-get install build-essential” -> “sudo apt-get i…

QT安装、构建套件(MSVC、MinGW)配置

QT安装、构建套件(MSVC、MinGW)配置 1. QT框架及QT Creator下载 登录QT官网-https://www.qt.io/download。 点击downloads for open source users 在页面最下方&#xff0c;点击Download the QT online Installer。 在安装网页的最下方处有一行小字 “We do recommend yo…

QT linux安装

转载地址&#xff1a;http://www.cnblogs.com/tangkaixuan/p/6504102.html 文章来自https://lug.ustc.edu.cn/sites/qtguide/ 1.4 Qt在Linux下安装 Qt在Linux系统里的安装要稍微复杂一些&#xff0c;因为Linux发行版众多&#xff0c;所以安装过程有些差异。 由于Linux系统都可…

Qt国内镜像安装

下载安装程序 https://download.qt.io/official_releases/online_installers/ 使用国内镜像打开安装程序 G:\下载\qt-unified-windows-x64-4.5.1-online.exe --mirror https://mirror.nju.edu.cn/qt清华源 https://mirrors.tuna.tsinghua.edu.cn/qt/online/qtsdkrepository/win…

Qt下载与安装

一、Qt和Qt Creator的区别 Qt是C的一个库&#xff0c;或者说是开发框架&#xff0c;里面集成了一些库函数&#xff0c;提高开发效率。 Qt Creator是一个IDE&#xff0c;就是一个平台&#xff0c;一个开发环境&#xff0c;类似的比如说VS&#xff0c;也可以进行Qt开发&#xff…

Ubuntu 安装QT

一、最近这家公司接到一个订单&#xff0c;客户使用到国产操作系统&#xff0c;意味着需要使用到 Linux 系统&#xff0c;于是乎&#xff0c;之前的东西又要捡起来&#xff0c;而且&#xff0c;平时代码主要是windows 平台&#xff0c;这次需要将代码移植到linux 平台&#xff…

QT的安装------QT

由于现在的qt都是线上下载了&#xff0c;那我们就去qt的官网下载 download.qt.io 我们选择倒数第二个------archive(档案)&#xff0c;顺便学一下英文。 然后选择online install&#xff08;在线安装&#xff09; 身为先进人&#xff0c;当然选择最新的版本&#xff08;团新版…

VS+QT安装配置

心血来潮&#xff0c;装个QT&#xff0c;遇到好多问题&#xff0c;记录一下&#xff08;铭记那些踩过的坑&#xff09; 软件版本&#xff1a;vs是2022&#xff0c;qt是6.3.1 qt下载地址&#xff1a;Download Qt | Develop Desktop & Embedded Systems | Qt 点进去往下翻&…

Windows Qt安装教程

目录 一、Qt安装包下载二、Qt安装流程 一、Qt安装包下载 Qt官网&#xff1a;https://download.qt.io/ Qt官方提供的专门的资源下载网站&#xff0c;所有的开发环境和相关工具都可以从这里下载&#xff0c;Qt 官方下载网站如下图&#xff1a; 点击进入archive目录&#xff0c;…

Qt安装教程-详细

本文主要介绍了Qt5.9.7的安装步骤。 Qt下载 Qt的下载地址: http://download.qt.io/archive/qt/ qt-opensource-windows-x86-5.9.7.exe 是一个综合的安装包(5.8之前分开下载各个编译器版本SDK)&#xff0c;下载后安装的时候可以选择安装哪个编译器对应的SDK。一般可选MinGW 或…