【算法】浅析动态规划

ops/2024/9/24 5:35:46/

动态规划介绍与使用

1. 算法定义

动态规划(Dynamic Programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学等领域中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

2. 诞生背景

动态规划诞生于20世纪50年代,由美国数学家理查德·贝尔曼提出。当时,为了解决多阶段决策问题,贝尔曼提出了动态规划这一概念。

3. 发展历程

自贝尔曼提出动态规划以来,这一方法在多个领域得到了广泛的应用和发展。以下是动态规划的主要发展历程:

  1. 1950年代:贝尔曼提出动态规划基本理论。
  2. 1960年代:动态规划在运筹学、控制理论等领域得到应用。
  3. 1970年代:动态规划开始应用于计算机科学领域,如算法设计。
  4. 1980年代至今:动态规划在人工智能、生物信息学等领域取得显著成果。

4. 特点

动态规划具有以下特点:

  1. 最优子结构:问题的最优解包含其子问题的最优解。
  2. 子问题重叠:动态规划将原问题分解为多个子问题,这些子问题不是独立的,而是重叠的。
  3. 无后效性:某阶段的状态一旦确定,就不受之后阶段的影响。

5. 基本原理

动态规划的基本原理是将复杂问题分解为若干个相互重叠的子问题,从最简单的子问题开始求解,并将子问题的解存储起来,避免重复计算。最后,通过子问题的解得到原问题的解。

6. 应用领域

动态规划在以下领域有广泛应用:

  1. 计算机科学:算法设计、字符串匹配、图像处理等。
  2. 经济学:资源分配、投资策略、价格决策等。
  3. 生物信息学:基因序列比对、蛋白质结构预测等。

7. 实例理解

以斐波那契数列为例,其递推公式为:F(n) = F(n-1) + F(n-2),其中F(0) = 0,F(1) = 1。

F(0) = 0
F(1) = 1
F(2) = F(1) + F(0) = 1
F(3) = F(2) + F(1) = 2
F(4) = F(3) + F(2) = 3
...

通过动态规划,我们可以将F(n)分解为F(n-1)和F(n-2)两个子问题,从而避免重复计算。

8. 代码示例

以下是一个使用Python实现的斐波那契数列的动态规划代码示例:

def fibonacci(n):if n <= 1:return ndp = [0] * (n+1)dp[1] = 1for i in range(2, n+1):dp[i] = dp[i-1] + dp[i-2]return dp[n]
print(fibonacci(10))

9. 代码分步讲解

  1. 定义一个名为fibonacci的函数,参数为n,表示求斐波那契数列的第n项。
  2. 判断n的值,如果小于等于1,直接返回n
  3. 创建一个长度为n+1的列表dp,用于存储子问题的解。
  4. 初始化dp[1] = 1,因为斐波那契数列的第二项为1。
  5. 使用一个for循环,从2遍历到n,计算每个子问题的解,并存储在dp列表中。
  6. 返回dp[n],即斐波那契数列的第n项。

通过以上步骤,我们成功使用动态规划求解了斐波那契数列问题。

10. 实例理解(进阶)

下面我们将使用动态规划来解决一个相对复杂的问题:最长公共子序列(Longest Common Subsequence, LCS)问题。这个问题是寻找两个或多个序列中最长的子序列,该子序列在原序列中是按相同顺序出现的,但不要求连续。

示例:

input:str1 = 123456 str2 = 234567output:LCS = 23456

1. 问题定义

给定两个字符串 str1str2,找出它们的最长公共子序列的长度。

2. 动态规划思路

  1. 创建一个二维数组 dp,其中 dp[i][j] 表示 str1 的前 i 个字符和 str2 的前 j 个字符的最长公共子序列的长度。
  2. 初始化 dp 的第一行和第一列为0,因为任何一个字符串与空字符串的最长公共子序列长度都是0。
  3. 遍历 str1str2 的字符,如果当前字符相等,则 dp[i][j] = dp[i-1][j-1] + 1;否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1])
  4. 最终 dp[str1.length()][str2.length()] 就是两个字符串的最长公共子序列的长度。

3. 代码分段

初始化部分
def longest_common_subsequence(str1, str2):m, n = len(str1), len(str2)# 创建一个 (m+1)x(n+1) 的二维数组,初始化为0dp = [[0] * (n + 1) for _ in range(m + 1)]
动态规划填表
    # 填充 dp 表for i in range(1, m + 1):for j in range(1, n + 1):if str1[i - 1] == str2[j - 1]:dp[i][j] = dp[i - 1][j - 1] + 1else:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
返回结果
    # 返回最长公共子序列的长度return dp[m][n]

4. 整体代码

def longest_common_subsequence(str1, str2):# 获取两个字符串的长度m, n = len(str1), len(str2)# 初始化动态规划表,大小为 (m+1)x(n+1),初始值为0dp = [[0] * (n + 1) for _ in range(m + 1)]# 填充动态规划for i in range(1, m + 1):for j in range(1, n + 1):# 如果当前字符相等,更新 dp 表的值if str1[i - 1] == str2[j - 1]:dp[i][j] = dp[i - 1][j - 1] + 1else:# 如果当前字符不相等,取上方和左方中的最大值dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])# 返回最长公共子序列的长度return dp[m][n]
# 测试代码
str1 = "ABCBDAB"
str2 = "BDCAB"
print(longest_common_subsequence(str1, str2))  # 输出应为4,最长公共子序列是 "BCAB"

以上代码展示了如何使用动态规划来解决最长公共子序列问题。代码中的注释说明了每一部分的作用和解决问题的思路。


http://www.ppmy.cn/ops/85913.html

相关文章

阿里云图片文件上传

一,官网地址 https://help.aliyun.com/document_detail/84781.html一切依据于官网 二,导入依赖 <dependencies><!-- 阿里云oss依赖 --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId>&l…

Live800:跨渠道客户服务:无缝衔接,随时随地满足客户需求

在当今这个数字化快速发展的时代&#xff0c;客户对于服务的需求已经不再局限于单一渠道。他们希望通过多种渠道&#xff0c;如电话、电子邮件、社交媒体、在线聊天等&#xff0c;随时随地获得所需的服务。因此&#xff0c;跨渠道客户服务成为了企业提升客户满意度和忠诚度的关…

labview四字节转浮点数

1.labview四字节转浮点数 2.Labview怎么把串口接收到的数据转换成浮点数&#xff1f; Labview怎么把串口接收到的数据转换成浮点数&#xff1f;

2024 微信小程序 学习笔记 第二天

1. WXML 模板语法 数据绑定 事件绑定 条件渲染 列表渲染 2. WXSS 模板样式 rpx 样式导入 全局和局部样式 3. 全局配置 window tabBar 配置tabBar案例 4. 网络数据请求 Get请求 Post 请求 加载时请求 5. 案例 -本地生活&#xff08;首页&#xff09; 导航栏 轮播图 九宫格效果…

披荆斩棘:Python开发者在市场低迷期快速找到工作的策略

披荆斩棘&#xff1a;Python开发者在市场低迷期快速找到工作的策略 在瞬息万变的科技领域&#xff0c;市场低迷期对各个领域的专业人士来说都充满了挑战。Python开发者以其灵活性和专业性著称&#xff0c;但也无法完全避免经济波动的影响。然而&#xff0c;通过采取正确的策略…

如何使用 SQLite ?

SQLite 是一个轻量级、嵌入式的关系型数据库管理系统&#xff08;RDBMS&#xff09;。它是一种 C 库&#xff0c;实现了自给自足、无服务器、零配置、事务性 SQL 数据库引擎。SQLite 的源代码是开放的&#xff0c;完全在公共领域。它被广泛用于各种应用程序&#xff0c;包括浏览…

面完英伟达算法岗,心态崩了。。。

最近这一两周看到不少互联网公司都已经开始秋招提前批了。不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解…

【Linux】-----工具篇(yum介绍)

目录 Ⅰ、是什么&#xff1f; Ⅱ、Linux下安装软件的三种方式 ①源代码安装 ②rpm包安装 ③yum安装 Ⅲ、yum相关操作 1.查看软件包 2.安装软件 3.卸载软件 Ⅳ、yum本地配置 Ⅰ、是什么&#xff1f; yum是包管理器&#xff0c;也就像一个软件下载安装管理的客户端&…