深度剖析动态规划算法:原理、优势与实战

概述

动态规划是一种优化技术,通常用于解决那些可以分解为子问题的问题。它的核心思想是将大问题分解成小问题,通过解决小问题来构建大问题的解。这种方法通常用于解决最优化问题,其中目标是找到最佳解决方案,通常是最大化或最小化某个值。

核心原理

动态规划算法的核心原理是将一个大问题分解成一系列较小的子问题,然后解决每个子问题并将其结果存储起来,以便后续使用。这有助于避免重复计算,提高了算法的效率。动态规划通常包括以下步骤:

  1. 定义状态(State):明确定义问题的状态,通常使用一个或多个变量来表示问题的不同方面。

  2. 确定状态转移方程(Transition Equation):找到问题状态之间的关系,以便从一个状态转移到另一个状态。

  3. 初始化(Initialization):初始化状态转移表或数组,将初始状态的值填入表中。

  4. 计算和存储(Computation and Storage):使用状态转移方程计算所有可能的状态,并将结果存储在表中。

  5. 返回结果(Return Result):根据存储的信息,计算并返回问题的最终结果。

优势

动态规划具有以下优势:

  1. 高效性:动态规划算法通常具有较低的时间复杂度,适用于大规模问题。

  2. 简单性:相对于某些复杂的算法,动态规划的实现相对简单。

  3. 实用性:动态规划适用于许多实际问题,特别是那些具有贪心选择性质的问题。

实际应用

动态规划算法的应用非常广泛,其中包括以下一些常见问题:

1、最长公共子序列(Longest Common Subsequence)

问题描述:给定两个字符串 s1 和 s2,找出它们的最长公共子序列。

解决方法: 使用动态规划来解决,创建一个二维DP表格,通过比较字符是否相等来更新表格中的值,最终返回表格右下角的值,即最长公共子序列的长度。

思路说明:

  • 创建一个二维DP表格,其中dp[i][j]表示字符串 s1 的前 i 个字符和字符串 s2 的前 j 个字符的最长公共子序列的长度。
  • 初始化第一行和第一列为0,因为一个空字符串与任何字符串的最长公共子序列长度都为0。
  • 通过迭代每个字符,比较字符是否相等,根据相等与不相等的情况来更新DP表格中的值。
  • 返回DP表格右下角的值,即最长公共子序列的长度。

python示例

def longest_common_subsequence(s1, s2):"""计算两个字符串的最长公共子序列的长度Args:s1 (str): 第一个字符串s2 (str): 第二个字符串Returns:int: 最长公共子序列的长度"""m, n = len(s1), len(s2)dp = [[0] * (n + 1) for _ in range(m + 1)]for i in range(1, m + 1):for j in range(1, n + 1):if s1[i - 1] == s2[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]# 示例数据
s1 = "abcde"
s2 = "ace"
result = longest_common_subsequence(s1, s2)
print("最长公共子序列长度:", result)# 运行结果
最长公共子序列长度: 3

java示例

public class LongestCommonSubsequence {public static int longestCommonSubsequence(String text1, String text2) {int m = text1.length();int n = text2.length();int[][] dp = new int[m + 1][n + 1];for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {if (text1.charAt(i - 1) == text2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[m][n];}// 示例数据public static void main(String[] args) {// 示例输入String text1 = "abcde";String text2 = "ace";// 计算最长公共子序列长度int result = longestCommonSubsequence(text1, text2);// 输出结果System.out.println("最长公共子序列长度: " + result);}
}// 运行结果
最长公共子序列长度: 3

2、背包问题(Knapsack Problem)

问题描述:给定一组物品,每个物品都有自己的重量和价值,以及一个容量有限的背包。目标是选择哪些物品放入背包,以使得背包中的物品总价值最大。

解决方法: 使用动态规划来解决,创建一个二维DP表格,通过迭代每个物品和容量来更新表格中的值,最终返回表格右下角的值,即最大价值。

思路说明:

  • 创建一个二维DP表格,其中dp[i][w]表示前 i 个物品放入容量为 w 的背包中所能获得的最大价值。
  • 初始化第一行和第一列为0,表示没有物品或容量为0时的最大价值都是0。
  • 通过迭代每个物品和容量,比较是否放入当前物品或不放入当前物品,根据不同情况来更新DP表格中的值。
  • 返回DP表格右下角的值,即最大价值。

python示例

def knapsack(weights, values, capacity):"""背包问题:选择不同物品以获得最大价值Args:weights (List[int]): 物品的重量列表values (List[int]): 物品的价值列表capacity (int): 背包的容量限制Returns:int: 背包问题的最大价值"""n = len(weights)dp = [[0] * (capacity + 1) for _ in range(n + 1)]for i in range(1, n + 1):for w in range(1, capacity + 1):if weights[i - 1] <= w:dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1])else:dp[i][w] = dp[i - 1][w]return dp[n][capacity]# 示例数据
weights = [2, 5, 10]
values = [10, 20, 30]
capacity = 15
result = knapsack(weights, values, capacity)
print("背包问题最大价值:", result)# 运行结果
背包问题最大价值: 60

java示例

public class KnapsackProblem {public static int knapsack(int[] weights, int[] values, int capacity) {int n = weights.length;int[][] dp = new int[n + 1][capacity + 1];for (int i = 1; i <= n; i++) {for (int w = 1; w <= capacity; w++) {if (weights[i - 1] <= w) {dp[i][w] = Math.max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1]);} else {dp[i][w] = dp[i - 1][w];}}}return dp[n][capacity];}// 示例数据public static void main(String[] args) {// 示例输入int[] weights = {2, 5, 10};int[] values = {10, 20, 30};int capacity = 15;// 计算背包问题的最大价值int result = knapsack(weights, values, capacity);// 输出结果System.out.println("背包问题最大价值: " + result);}
}// 运行结果
背包问题最大价值: 60

3、最长递增子序列(Longest Increasing Subsequence)

问题描述:给定一个整数数组 nums,找到其中的一个最长递增子序列的长度。

解决方法: 使用动态规划来解决,创建一个一维DP数组,通过比较元素大小来更新数组中的值,最终返回数组中的最大值,即最长递增子序列的长度。

思路说明:

  • 创建一个一维DP数组,其中dp[i]表示以第 i 个元素结尾的最长递增子序列的长度。
  • 初始化所有元素为1,表示每个元素自身构成的子序列。
  • 通过迭代每个元素,比较元素与前面元素的大小,根据不同情况来更新DP数组中的值。
  • 返回DP数组中的最大值,即最长递增子序列的长度。

python示例

def length_of_lis(nums):"""计算给定整数数组的最长递增子序列的长度Args:nums (List[int]): 整数数组Returns:int: 最长递增子序列的长度"""if not nums:return 0n = len(nums)dp = [1] * n  # 初始化所有元素为1,表示每个元素自身构成的子序列for i in range(1, n):for j in range(i):if nums[i] > nums[j]:dp[i] = max(dp[i], dp[j] + 1)return max(dp)# 示例数据
nums = [10, 9, 2, 5, 3, 7, 101, 18]
result = length_of_lis(nums)
print("最长递增子序列的长度:", result)# 运行结果
最长递增子序列的长度: 5

java示例

import java.util.Arrays;public class LongestIncreasingSubsequence {public static int lengthOfLIS(int[] nums) {if (nums.length == 0) {return 0;}int n = nums.length;int[] dp = new int[n];Arrays.fill(dp, 1);for (int i = 1; i < n; i++) {for (int j = 0; j < i; j++) {if (nums[i] > nums[j]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}}int maxLength = 1;for (int len : dp) {maxLength = Math.max(maxLength, len);}return maxLength;}// 示例数据public static void main(String[] args) {// 示例输入int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};// 计算最长递增子序列的长度int result = lengthOfLIS(nums);// 输出结果System.out.println("最长递增子序列的长度: " + result);}
}// 运行结果
最长递增子序列的长度: 5

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

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

相关文章

Prometheus集成AlertManager实现告警

Prometheus Server配置 使用yml格式编写一个告警规则配置文件 groups: - name: 账号中心rules:# 检测状态报警- alert: 账号中心指标状态告警expr: ssl_expire_days 0for: 0slabels:severity: 1annotations:instance: "账号中心 实例 {{$labels.instance}} 指标告警&qu…

Arduino与Proteus仿真-WiFi TCP客户端数据通信

TCP客户端数据通信 文章目录 TCP客户端数据通信1、软件准备2、硬件准备3、仿真电路原理图4、仿真代码实现5、仿真结果本文将介绍Arduino在Protues仿真环境中作为TCP客户端,如何与TCP服务器进行数据通信。 1、软件准备 1)Arduino IDE或 VSCode + PlatformIO 2)Proteus电路仿…

【面试题精讲】SpringTemplate使用

“ 有的时候博客内容会有变动&#xff0c;首发博客是最新的&#xff0c;其他博客地址可能会未同步,认准https://blog.zysicyj.top ” 首发博客地址 文章更新计划 系列文章地址 1. 什么是SpringTemplate? SpringTemplate是Spring框架提供的一个用于简化数据库操作的工具类。它封…

Java集成支付宝沙箱支付,详细教程(SpringBoot完整版)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、开发前准备&#xff1f;二、使用步骤1、引入库2、配置在 application.yml 里面进行配置&#xff1a;3、alipay的java配置&#xff1a;AplipayConfig.java4、支付…

安达发|APS排单软件中甘特图的应用

近几年来&#xff0c;企业对生产效率和管理水平的要求越来越高。为了提高生产效率&#xff0c;降低生产成本&#xff0c;许多企业开始引入先进的生产计划与调度系统&#xff08;APS&#xff09;&#xff0c;实现生产过程的自动化、智能化管理。APS排产软件是一种能够根据企业的…

Spring源码相关

总分结构回答&#xff0c;突出关键接口、类、方法名 run -> AbstractApplicationContext.refresh&#xff08;&#xff09;程序的入口 在IOC中的操作都是基于DefaultListableBeanFactory bd对象保存在map集合中 refresh方法宝包括了整个Spring的执行流程和bean的完整生命…

解锁新机遇——易天欧洲ECOC通讯展预告,精彩即将开始!

九月初&#xff0c;第24届中国光博会落下帷幕&#xff0c;易天在展会上收获了来自同行和客户的高度满意。但易天发展和学习的脚步从未停歇。十月&#xff0c;易天将整装待发前赴英国参加2023第28届ECOC欧洲光通讯展。 展会简介 欧洲光纤通讯展是欧洲规模大的光纤通讯展会&…

215 数组中的第K个最大元素

满足时间复杂度o(n)的方法&#xff1a; 快排的思想 class Solution{ public:int findKthLargest(vector<int>& nums,int k){return quickSelect(nums,k);} private:int quickSelect(vector<int>& nums,int k){//随机选择基数int privotnums[rand()%nums…

verilog学习笔记(1)module实例化

兜兜转转又回来学硬件了&#xff0c;哎&#xff0c;命啊&#xff01; 我的答案&#xff08;有bug&#xff09;&#xff1a; module top_module ( input a, input b, output out );wire w1;wire w2;wire w3;mod_a mod_a_inst1(.in1(w1),.in2(w2),.out(w3) );assign w1 a…

2023-Chrome插件推荐

Chrome插件推荐 一键管理扩展 链接 https://chromewebstore.google.com/detail/lboblnfejcmcaplhnbkkfcienhlhpnni 介绍 一键开启、禁用Chrome插件。 Checker Plus for Gmail™ 链接 https://jasonsavard.com/zh-CN/Checker-Plus-for-Gmail https://chromewebstore.goo…

不安全的反序列化

文章目录 一、 序列化与反序列化1.1 引例1.2 序列化实例1.2.1 定义一个类1.2.2 创建对象1.2.3 反序列化1.2.4 对象注入 二、 漏洞何在2.1 漏洞触发2.1.1 有一个类2.1.2 有一个对象2.1.3 反序列化执行代码 2.2 为什么会这样 三、反序列化漏洞攻防3.1 PHP反序列化实例3.2 Java 反…

计算机毕业设计 基于微信小程序的校园商铺系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【Java 基础篇】Java 模块化详解

Java 9引入了一项重要的功能&#xff1a;模块化&#xff08;Module System&#xff09;。模块化是一种将代码和资源封装到可重用和独立的单元中的方法&#xff0c;它有助于改善代码的可维护性、可重用性和安全性。本文将介绍Java模块化的基本概念、如何创建和使用模块以及一些最…

AI数字人:最强声音驱动面部表情模型VideoReTalking

目录 1 VideoReTalking论文解读 1.1 介绍 1.2 相关工作 1.2.1 视频编辑中的音频配音 1.2.2 基于音频的单图像面部动画 1.3 框架 1.3.1 语义引导重演网络 1.3.2 口型同步网络 1.3.3 身份感知增强网络 1.3.4 后期处理 1.4 训练 1.4.1 每个模块的训练 1.4.2 评估 1.…

JSP ssm 零配件管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java ssm 零配件管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用…

注入之SQLMAP(工具注入)

i sqlmap是一个自动化的SQL注入工具&#xff0c;其主要功能是扫描&#xff0c;发现并利用给定的URL和SQL注入漏洞&#xff0c;其广泛的功能和选项包括数据库指纹&#xff0c;枚举&#xff0c;数据库提权&#xff0c;访问目标文件系统&#xff0c;并在获取操作权限时执行任…

RabbitMQ生产故障问题分析

1. 问题引发 由某个服务BI-collector-xx队列出现阻塞&#xff0c;影响很整个rabbitMQ集群服务不可用&#xff0c;多个应用MQ生产者服务出现假死状态&#xff0c;系统影响面较广&#xff0c;业务影响很大。当时为了应急处理&#xff0c;恢复系统可用&#xff0c;运维相对粗暴的把…

java Spring Boot2.7实现一个简单的爬虫功能

首先 我们要在 pom.xml 中注入Jsoup 这是一个简单的java爬虫框架 <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.14.1</version> </dependency>然后这里我们直接用main吧 做简单一点 我…

Linux 终端命令总结

一、常用的七条命令 命令 对应英文作用lslist查看当前文件夹下的内容pwdprint work directory查看当前所在文件夹cd [目录名]change directory切换文件夹 touch [文件名]touch如果文件不存在新建文件mkdir [目录名]make directory创建目录rm[文件名]remo…

如何在Vue 3项目中使用Jest配置生成测试报告

1. 介绍 在Vue 3项目中使用Jest进行单元测试是一种常见的做法&#xff0c;它可以帮助我们验证代码的正确性和稳定性。而生成测试报告可以帮助我们更好地了解测试覆盖率和测试结果&#xff0c;以便更好地优化和改进我们的代码。本文将介绍如何在Vue 3项目中配置Jest&#xff0c…