动态规划:基本概念

Dynamic Programming

动态规划(Dynamic Programming, DP) 是一种算法设计技巧,通常用来解决具有重叠子问题和最优子结构性质的问题。它通过将问题分解为更小的子问题,逐步解决这些子问题并将结果存储起来,以避免重复计算,从而提高效率。


1. 特点

1.1 重叠子问题

在许多递归问题中,计算过程中会多次遇到相同的子问题。如果我们每次遇到这些子问题时都重新计算,会导致大量的重复计算和效率低下。重叠子问题的思想是通过将子问题的结果存储起来,避免重复计算,从而提高效率。

举例

斐波那契数列

递归关系式

T ( n ) = T ( n − 1 ) + T ( n − 2 ) T(n)=T(n-1)+T(n-2) T(n)=T(n1)+T(n2)

计算T(3)

T ( 3 ) = T ( 2 ) + T ( 1 ) = T ( 1 ) + T ( 0 ) + T ( 1 ) \begin{aligned} T(3) &= T(2) + T(1) \\ &= T(1) + T(0) + T(1) \end{aligned} T(3)=T(2)+T(1)=T(1)+T(0)+T(1)

这里我们可以看见T(1)被多次计算

这个多次计算的T(1)便被称为重复子问题

如果我们用递归来解决这个问题

int fin(int n){if(n==1)return 1;if(n==0)return 0;return fin(n-1)+fin(n-2);
}

画出递归树

在这里插入图片描述

我们可以看到有多次递归调用都是重复的,即出现了重复子问题。

1.2 记忆化存储

继续探究斐波那契问题

我们之前发现使用递归解决问题时出现了多次递归调用是重复的
在这里插入图片描述

我们可以将这些重复子问题的结果储存起来,这样下一次需要解决这个子问题的时候,只需要访问之前的结果就可以了。

模拟实现

int fin(int n){std::vector<int>Fin(n+1);Fin[0]=0;Fin[1]=1;for(int i=2;i<=n;i++){Fin[i]=Fin[i-1]+Fin[i-2];}return Fin[n];
}

可以看出来我们是从最小子问题来逐渐递推至最后的答案,这也被称为自底而上的算法

1.4 状态转移方程

我们来看斐波那契数列的递推关系式

T ( n ) = T ( n − 1 ) + T ( n − 2 ) T(n)=T(n-1)+T(n-2) T(n)=T(n1)+T(n2)

这里我们可以看出,如果我们想得到第n项的答案,我们就要知道第n-1项和第n-2项的答案

T ( n ) ← 这个第 n 项的答案,就定义为一个状态 T(n) \gets 这个第n项的答案,就定义为一个状态 T(n)这个第n项的答案,就定义为一个状态

状态转移方程表示的就是某一个状态和其他状态之间的关系

T ( n ) = T ( n − 1 ) + T ( n − 2 ) T(n)=T(n-1)+T(n-2) T(n)=T(n1)+T(n2)

这个方程就表示第n个状态是由第n-1个状态和第n-2个状态决定

1.5 最优子结构

还是看斐波那契数列

我们如果要求出第n个状态的状态值,那么我们一定是使用第n-1个状态和第n-2个状态的值来计算的。

由于我们的状态转移方程是确定的,这里求出的一定是最优解。

给出定义

如果一个问题的最优解包含了其子问题的最优解,则称这个问题具有最优子结构性质。


2. 用动态规划来设计算法的步骤

2.1 理解问题并确定子问题

首先,理解斐波那契数列的问题。斐波那契数列定义如下:

F ( n ) = F ( n − 1 ) + F ( n − 2 ) F(n) = F(n-1) + F(n-2) F(n)=F(n1)+F(n2)

其初始条件为:
F ( 0 ) = 0 F(0) = 0 F(0)=0
F ( 1 ) = 1 F(1) = 1 F(1)=1

这个问题可以分解为子问题,即计算第 ( n ) 项的值依赖于第 ( n-1 ) 项和第 ( n-2 ) 项的值。

2.2 定义状态

定义状态 ( dp[i] ) 表示斐波那契数列第 ( i ) 项的值。

d p [ i ] ← 斐波那契数列第 i 项的值 dp[i] \gets 斐波那契数列第 i 项的值 dp[i]斐波那契数列第i项的值

2.3 确定状态转移方程

状态转移方程基于斐波那契数列的递归定义,可以写作:
d p [ i ] = d p [ i − 1 ] + d p [ i − 2 ] dp[i] = dp[i-1] + dp[i-2] dp[i]=dp[i1]+dp[i2]

2.4 确定初始状态和边界

根据斐波那契数列的初始条件,初始化状态:

d p [ 0 ] = 0 dp[0] = 0 dp[0]=0
d p [ 1 ] = 1 dp[1] = 1 dp[1]=1

2.5 利用状态转移方程计算状态值

使用状态转移方程从初始状态开始逐步计算到目标状态值。

#include <vector>int fib(int n) {if (n <= 1) return n;std::vector<int> dp(n + 1);dp[0] = 0;dp[1] = 1;for (int i = 2; i <= n; ++i) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];
}

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

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

相关文章

外星人Alienware m18R1 原厂Windows11系统

装后恢复到您开箱的体验界面&#xff0c;包括所有原机所有驱动AWCC、Mydell、office、mcafee等所有预装软件。 最适合您电脑的系统&#xff0c;经厂家手调试最佳状态&#xff0c;性能与功耗直接拉满&#xff0c;体验最原汁原味的系统。 原厂系统下载网址&#xff1a;http://w…

“拿来主义”学习边框动画(附源码)

“拿来主义”学习边框动画&#xff0c;附源码&#xff0c;CV可用 扫码关注&#xff1a;小拾岁月&#xff0c;发送 “边框动画”&#xff0c;获取源码。 需求分析 从边框的旋转动画&#xff0c;我们可以看出&#xff0c;可以在按钮元素的下方添加给 360旋转 的元素。同时&…

观察者模式(大话设计模式)C/C++版本

观察者模式 扩展&#xff1a;观察者模式——委托 C 参考&#xff1a;https://www.cnblogs.com/Galesaur-wcy/p/15905936.html #include <iostream> #include <list> #include <memory> #include <string> using namespace std;// Observer类 抽象观…

人工智能导论笔记

有关知识表示和推理的零碎知识点 人工智能导论复习题和概念-CSDN博客 机器学习篇 机器学习分类&#xff08;根据样本数据是否带有标签&#xff09;&#xff1a;监督的机器学习、无监督的机器学习、半监督学习。 监督学习又称为“有教师学习”。在监督学习中&#xff0c;模型…

MySQL 面试突击指南:核心知识点解析2

事务并发可能引发的问题 MySQL 是一个客户端/服务器架构的软件,对于同一个服务器来说,可以有多个客户端与之连接,每个客户端与服务器连接后,可以称为一个会话(Session)。每个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就…

什么是距离选通型水下三维激光扫描仪?(下)

距离选通激光水下成像的发展 距离选通激光成像技术始于上世纪60年代&#xff0c;受制于高性能脉冲激光器和选通成像器件发展的制约&#xff0c;激光距离选通成像技术在随后的二十年发展缓慢&#xff0c;直到20世纪90年代&#xff0c;随着硬件技术的不断成熟&#xff0c;该技术…

Prompt 提示词工程:翻译提示

近期在对计算机学习时&#xff0c;许多内容需要看原始的英文论文&#xff0c;对于我这种学渣来说特别不友好&#xff0c;&#x1f937;&#x1f3fb;‍♀️无奈只能一边看翻译&#xff0c;一边学习。 之前有搜到过专门的翻译工具&#xff0c;无奈都是按照字数算费用的&#xf…

【FreeRTOS】删除任务 用遥控器控制音乐

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 学习视频&#xff1a;【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS&#xff08;FreeRTOS教程 基于STM32&#xff0c;以实际项目为导向&#xff09;】 【精准空降到 01:22】 https://www.bilibili.com/video/BV1…

模拟原神圣遗物系统-小森设计项目,设计圣遗物词条基类

项目分析 首先需要理解圣遗物的方方面面 比如说圣遗物主词条部分和副词条部分都有那些特点 稍等一会&#xff1a;原神&#xff0c;启动&#xff01; 在此说明了什么&#xff1f; 这是完全体 &#xff1a;主副 词条都有 如果 升级直接暴击率 那么就留点 或者是另外的元素充能 …

关于笔记本电脑连接电源时触摸板失灵、卡顿、乱飘的问题

目录 前言 问题原因 解决方法 前言 我查阅了相关的资料和方法如下&#xff08;很感谢这位楼主大佬提供的问题所在&#xff09;&#xff1a; 问题原因 解决方法 那么解决方法无非就是几种&#xff08;方法仅供参考&#xff0c;不排除一些危险性&#xff09;&#xff1a; 1…

“论面向对象的建模及应用”必过范文,软考高级,系统架构设计师论文

论文真题 软件系统建模是软件开发中的重要环节,通过构建软件系统模型可以帮助系统开发人员理解系统,抽取业务过程和管理系统的复杂性,也可以方便各类人员之间的交流。软件系统建模是在系统需求分析和系统实现之间架起的一座桥梁,系统开发人员按照软件系统模型开发出符合设…

【人工智能】—XGBoost算法在构建互联网防火墙异常行为识别模型应用案例

摘要&#xff1a; 近年来&#xff0c;各地党委、政府加快推进新型工业化&#xff0c;部署实施制造强市战略&#xff0c;提出工业企业“智改数转”是推动全市工业经济稳增长的重要引擎&#xff0c;更是稳增长、促发展的重要抓手。今天博主就以互联网防火墙异常行为识别为例给大家…

PCM、WAV,立体声,单声道,正弦波等音频素材

1&#xff09;PCM、WAV音频素材&#xff0c;分享给将要学习或者正在学习audio开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 常用的Audio PCM WAV不同采样率&#xff0c;不同采样深度&#…

信息安全基础知识(完整)

信息安全基础知识 安全策略表达模型是一种对安全需求与安全策略的抽象概念表达&#xff0c;一般分为自主访问控制模型&#xff08;HRU&#xff09;和强制访问控制模型&#xff08;BLP、Biba&#xff09;IDS基本原理是通过分析网络行为&#xff08;访问方式、访问量、与历史访问…

linux中Java程序调用C程序中方法的实现方式浅析

在Linux中&#xff0c;Java程序可以通过JNI&#xff08;Java Native Interface&#xff09;来调用C程序的方法。 Linux系统环境&#xff0c;Java调用C的主要流程如下&#xff1a; 1、创建Java类文件&#xff0c;如NativeLibrary.java 2、编写Java代码&#xff0c;加载.so共享库…

mysql中的datetime类型在Java中到底对应哪个时间类型?

因为MySQL中用的是datetime类型&#xff08;年月日 时分秒&#xff09; java.sql.Date 在Java中用 java.sql.Date 接收 但是得到的却只有年月日 前端接收到的是时间戳 java.time.LocalDateTime 在Java中使用 java.time.LocalDateTime 接收 得到的是带时区的时间 前端接收到的…

ROS中的TF是什么

在ROS (Robot Operating System) 中&#xff0c;tf::TransformBroadcaster 是一个用于发布坐标变换信息的重要类&#xff0c;尤其在处理机器人定位和导航数据时非常常见。tf::TransformBroadcaster 对象允许你广播从一个坐标系到另一个坐标系的变换关系&#xff0c;这对于多传感…

web中间件漏洞-Redis漏洞未授权访问漏洞-写webshell、写ssh公钥

web中间件漏洞-Redis漏洞未授权访问漏洞 利用redis未授权访问漏洞写webshell 利用redis未授权访问、攻击机向服务器写入webshell 从服务器查看写入的webshell 菜刀连接 利用redis未授权访问漏洞写ssh公钥 kali生成rsa公私钥对 ssh-keygen -t rsa 将公钥id_rsa.pub写入文…

33 - 连续出现的数字(高频 SQL 50 题基础版)

33 - 连续出现的数字 -- 开窗函数lead(col,n) 统计窗口内往下第n行值 -- over(partition by xxx) 按照xxx所有行进行分组 -- over(partition by xxx order by aaa) 按照xxx分组&#xff0c;按照aaa排序select distinct num as ConsecutiveNums from(select num,# 从当前记录获…

C语言第17篇:预处理详解

1、预定义符号 C语言设置了一些预定义符号&#xff0c;可以直接使用。预定义符号也是在预处理期间处理的。 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI…