#03动态规划

要点:

动态规划方法与贪心法、分治法的异同;

动态规划方法的基本要素与求解步骤;

动态规划方法的应用。

难点:

如何根据问题的最优子结构性质构造构造动态规划方法中的递归公式或动态规划方程


  • 动态规划的基本思想 
动态规划的实质

1) 分治思想:将原问题分解为更小、更易求解的子问题,然后对子问题进行求解,并最终产生原问题的解。

2) 解决冗余:求解过程中,所有子问题只求解一次并以表的方式保存,对于相同子问题并不重复求解而通过查表的方式获得。

动态规划和分治法的异同

1) 相同:都基于分治思想;

2) 不同:分治法中各个子问题是独立的,而动态规划方法中允许子问题之间存在重叠

  • 动态规划的3个基本要素 

1)最优子结构性质:(F(5)的最优解包括F(4)的最优解)

问题最优解包含其子问题的最优解。为动态规划的基础。基于最优子结构性质导出递归公式或动态规划基本方程是解决一切动态规划问题的基本方法。反证法证明。

2) 子问题重叠性质:(F(3)和F(2)被多次求解)

求解过程中有些子问题出现多次而存在重叠。第一次遇到就加以解决并保存,若再次遇到时无需重复计算而直接查表得到,从而提高求解效率。该性质不是必要条件,但无该性质该方法即没有优势。

3) 自底向上的求解方法:(Fibonacci数的第二种求解方法)

鉴于子问题重叠性质,采用自底向上的方法。先填停止条件,求解每一级子问题并保存,直至得到原问题的解

//斐波那契数列自顶向下递归求解: 
FIB1(n)  
IF n = 0     RETURN 0   
ELSE IF n = 1     RETURN 1   
ELSE RETURN FIB1(n-1) + FIB1(n-2)
//时间复杂性为O(1.618n),空间复杂性为O(n)。
//自底向上求解伪代码: 
FIB2(n)F[0] = 0 //F[0..n]F[1] = 1FOR i = 2 TO nF[i] = F[i-1] + F[i-2]RETURN F[n]
//其时间复杂性为O(n),空间复杂性为O(n)。
  • 动态规划求解的4个基本步骤

 (1)分析最优解的性质,以刻画最优解的结构特征 ——— 考察是否适合采用动态规划方法,即是否具备最优子结构性质

(2)递归定义最优值(即建立递归公式或动态规划方程),包括停止条件(递归出口)和递归体;

(3)以自底向上的方式计算出最优值,并记录相关信息。应充分利用子问题重叠性质;

(4)最终构造出最优解


备忘录方法(动态规划方法的变形)

相同点:用表格保存已经解决的子问题的解,下次需要时直接查表而无需重新计算;

不同点:①备忘录方法采用自顶向下的递归方式,动态规划是采用自底向上的递归方式;

②备忘录的控制结构和直接递归的结构同,区别在于备忘录方法为已有解的子问题建立备忘录待需要时查看;


最长公共子序列LCS问题

设序列X={$ x_1$,$ x_2$,…,$ x_m$}和Y={$y_1$,y_2,…,y_n}的最长公共子序列为Z={z_1,z_2,…,z_k} ,则:

x_m==y_n,则z_k==x_m==y_n,而且z_{k-1}x_{m-1}y_{n-1}的最长公共子序列;

x_my_nz_kx_m,则ZX_{m-1}Y的最长公共子序列;

x_my_nz_ky_ny_n,则ZXY_{n-1}的最长公共子序列。

以上,可以使用反证法进行证明。

LCS满足动态规划的条件:

LCS问题的子问题重叠性质: 在计算X和Y的LCS时,可能需要计算X_{m-1}YXY_{n-1}的LCS,很显然都包含了X_{m-1}Y_{n-1}的LCS。

LCS问题的最优子结构性质建立子问题最优值的递归关系:

用c[i][j]记录序列Xi和Yj的LCS的长度。其中,Xi={x1,x2,…,xi}和Yj={y1,y2,…,yj}分别为序列X和Y的第i个前缀和第j个前缀。 当i=0或j=0时,空序列是Xi和Yj的LCS。此时C[i][j]=0。其他情况下,由最优子结构性质可建立递归关系。

LCS问题的具体设计:

①确定合适的数据结构。采用二维数组c来存放各个子问题的最优解二维数组b记录各子问题最优值的来源(之前的递归公式上所附注的以上3种情况)

②初始化。令c[i][0]=0,c[0][j]=0,其中,0≤i≤m,0≤j ≤n。

③循环阶段。根据递归关系式,确定Xi和Yj的LCS的长度,0≤i≤m。对于每个i循环,0≤j ≤n。

④根据二维数组b记录的信息以自底向上的方式来构造该LCS问题的最优解

//基于DP动态规划求解LCS问题的伪代码如下:
LCS(X,Y)m = length(X)n = length(Y)FOR i = 1 TO mc[i][0] = 0FOR j = 1 TO nc[0][j] = 0FOR i = 1 TO mFOR j = 1 TO nIF X[i] == Y[j]c[i][j] = c[i-1][j-1] + 1b[i][j] = 1ELSE IF c[i-1][j] >= c[i][j-1]      //暗指x[i]!=y[j]  c[i][j] = c[i-1][j] b[i][j] = 3ELSEc[i][j] = c[i][j-1] b[i][j] = 2//else if和else 就是在如果两个字母不匹配 当前位置的状态取左边或者上边的最大值
//对于第一个if 两个字母匹配 当前位置的状态取左斜对角位置+1;
//O(m+n+m*n) -> O(n的平方)
//构造LCS问题最优解的伪代码如下:
LCS-PRINT(b,X,i,j)IF i == 0 OR j == 0 RETURNIF b[i][j] == 1LCS-PRINT(b,X,i-1,j-1)PRINT X[i]ELSE IF b[i][j] == 3LCS-PRINT(b,X,i-1,j)ELSELCS-PRINT(b,X,i,j-1) //b[i][j] == 2
//该算法的时复杂性为O(m+n)-> O(n) 
LCS的其他解决方法:
穷举搜索法

枚举Xm={x1,x2,…,xm}的所有子序列,并逐一检查每个子序列是否也为Yn={y1,y2,…,yn}的子序列,其中最长的即为Xm和Yn的最长公共子序列。

该算法的时复杂性为O(n2^m) -> O(n2^n),指数级;

直接递归法
//直接递归是自顶向下的
LCS-REC(X,Y,i,j,c,b)IF i == 0 OR j == 0 RETURN 0IF X[i] == Y[j]PRINT X[i] RETURN LCS-REC(X,Y,i-1,j-1,c,b) + 1 ELSERETURN MAX(LCS-REC(X,Y,i-1,j,c,b),LCS-REC(X,Y,i,j-1,c,b))

该算法的时复杂性为O(22^{min(m,n))}) -> O(2^n),指数级;


矩阵连乘

给定n个矩阵{A1, A2, A3, …, An},其中Ai与Ai+1 (i=1,2,3, …,n-1)是可乘的。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积所需要的数乘次数最少。

穷举法

设n个矩阵连乘的不同计算次序数为P(n)。每种加括号方式都可分解为两个子矩阵的加括号问题:(A1...Ak)(Ak+1…An):

动态规划方法

性质:最优子结构性质--反证法;

计算A[i:j]的最优次序所包含的计算矩阵子链 A[i:k]和A[k+1:j]的次序也是最优的:

设计算A[i:j],1≤i≤j≤n,所需要的最少数乘次数m[i,j],则原问题的最优值为m[1,n];

当i=j,A[i:j]=A[i:i]。因此,m[i,i]=0,i=1,2,…,n;

当i<j,m[i,j] = m[i,k]+m[k+1,j]+p_{i-1}p_kp_jA_i维数为P_{i-1} x P_i

//递归求解矩阵连乘问题的伪代码:
RECURSIVE-MATRIX-CHAIN(p,i,j,m,s)IF i == jm[i,j] = 0, s[i,j] = 0RETURNm[i,j] = ∞FOR k = i TO j-1q = RECURSIVE-MATRIX-CHAIN(p,i,k,m,s)+ RECURSIVE-MATRIX-CHAIN(p,k+1,j,m,s)+ pi-1pkpjIF q < m[i,j]m[i,j] = qs[i,j] = kRETURN m AND s
//采用DP求解矩阵连乘问题的伪代码:
MATRIX-CHAIN-ORDER-DP(n,p,m,s) //p[1..n+1]为n个矩阵的维数//m[1..n, 1..n]为最优值,s[1..n, 1..n]为最优决策FOR i = 1 TO nm[i,i] = 0FOR l = 2 TO n //l为链的长度FOR i = 0 TO n-l+1j = i+l-1m[i,j] = ∞FOR k = i TO j-1q = m[i,k] + m[k+1,j] + pi-1pkpjIF q < m[i,j]m[i,j] = qs[i,j] = kRETURN m AND s
//时间复杂度是n的三次方;空间复杂度是O(1);//采用DP求解矩阵连乘问题的伪代码:
MATRIX-CHAIN-ORDER-DP(n,p,m,s) //p[1..n+1]为n个矩阵的维数//m[1..n, 1..n]为最优值,s[1..n, 1..n]为最优决策FOR i = 1 TO nm[i,i] = 0FOR l = 2 TO n //l为链的长度FOR i = 0 TO n-l+1j = i+l-1m[i,j] = ∞FOR k = i TO j-1q = m[i,k] + m[k+1,j] + pi-1pkpjIF q < m[i,j]m[i,j] = qs[i,j] = kRETURN m AND s
//时间复杂性 O(n) ;空间复杂性:O(n)//主程序:
MATRIX-CHAIN-ORDER-DP-MAIN(p,n)//m[1..n, 1..n]为最优值,    //s[1..n, 1..n]为最优决策(m,s) = MATRIX-CHAIN-ORDER-DP(n,p,m,s)PRINT-OPTIMAL-PARENS(s,1,n)
// 时间复杂性:O(n3)  空间复杂性:O(n2)

算法设计与分析——矩阵连乘问题(动态规划) - 王陸 - 博客园 (cnblogs.com)

0-1背包问题 

动态规划

n个物品和1个背包。对物品i,其价值为vi,重量为wi,背包容量为W。如何选取物品装入背包,使背包中所装入的物品的总价值最大?其中,wi, W都是正整数。

 最优子结构性质:

设 (x1, x2,…, xn) 是所给0-1背包问题的一最优解,则 (x2,…, xn) 是下面相应子问题的一个最优解

//采用DP求解0-1背包问题的伪代码:
KNAPSACK-01-DP(w, v, W) //w为重量,v为价值,W为容量//C[1..n, 1..n]为最优值--最大价值FOR i = 1 TO nC[i,0] = 0FOR j = 1 TO W                   //可用容量C[0,j] = 0FOR i = 1 TO nFOR j = 1 TO WIF j < w[i]C[i,j] = C[i-1][j]         //装不下第i个物品ELSEC[i,j] = MAX{C[i-1][j],C[i-1][j-w[i]] + v[i]}   //在装下第i个物品和不装的价值最大判断 RETURN C //时间复杂度是O(nW) 空间复杂度O(1);//0-1背包问题的最优解构建的伪代码:
KNAPSACK-TRACEBACK-01(w,W,C,X) //w为重量,W为容量,C为最优值//X[1..n]为构建的最优解 -- 选择哪个物品放进背包;n = w.length – 1j = W                              //可用容量FOR i = n TO 1IF C[i][j] == C[i-1][j]X[i] = 0                  //现在这个物品的价值和上一个一样就不放入 ELSE                          X[i] = 1                   //放入,可用容量减去当前物品重量;j -= w[i]RETURN X
//时间复杂度是O(n)  空间复杂度是O(1);//主程序:
KNAPSACK-01-DP-MAIN(w,v,W) //w为重量,v为价值,W为容量KNAPSACK-01-DP(w,v,W,C)        --C存背包价值的最大化//X[1..n]为构建的最优解KNAPSACK-TRACEBACK(w,v,W,C,X)  --X存物品的有无
//时间复杂性:O(nW)。空间复杂性:O(nW);

贪心算法

在不超过背包的容量的情况下,尽可能多(指重量,如全部或部分)地选择更为贵重(指单位重量的价值最大)的物品,直至装满背包为止。

//基于贪心法求解背包问题的伪代码如下:
GREEDY-KNAPSACK(w, v, W) //w为重量,v为价值,W为容量SORT-ASC-BY-V(v,w) //按照物品的单位价值非降序排序,同时调整v和wn = w.length//x[1..n]为最优值,存放已选物品的相应重量。各元素初始化为0wRemained = W           //剩余重量是WFOR i = 1 TO n          IF wRemained <= 0       //无剩余重量 BREAK;ELSE IF wRemained >= w[i]   x[i] = 1            //存入wRemained = W – w[i]ELSEx[i] = 0            //不存入BREAKRETURN x

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

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

相关文章

算法与数据结构面试宝典——迭代与递归详解与示例(C#,C++)

文章目录 一、迭代与递归简介迭代递归 二、迭代与递归的应用场景迭代递归 三、迭代与递归的优缺点迭代优缺点递归优缺点 四、迭代与递归的示例及面试策略示例1&#xff1a;斐波那契数列&#xff08;迭代实现&#xff09;示例2&#xff1a;快速排序&#xff08;递归实现&#xf…

大学网页制作作品1

作品须知&#xff1a;1.该网页作品预计分为5个页面&#xff08;其中1个登录页面&#xff0c;1个首页主页面&#xff0c;3个分页面&#xff09;&#xff0c;如需要可自行删改增加页面。&#xff08;总共约800行html,1200行css,100行js&#xff09; 2.此网页源代码只用于学习和模…

R语言——数据与运算

练习基本运算&#xff1a; v <- c(2,4,6,9)t <- c(1,4,7,9)print(v>t)print(v < t)print(v t)print(v!t)print(v>t)print(v<t) v <- c(3,1,TRUE,23i)t <- c(4,1,FALSE,23i)print(v&t)print(v|t)print(!v)v <- c(3,0,TRUE,22i)t <- c(1,3,T…

【启明智显产品分享】Model4 工业级HMI芯片详解(三):高安全、防抄板

Model4 工业级HMI芯片详解系列专题&#xff08;三&#xff09;【高安全、防抄板】 随着物联网和智能设备的快速发展&#xff0c;设备安全认证的需求日益迫切。硬件安全认证和保护在确保设备和身份安全中发挥着不可替代的作用&#xff0c;需要与软件安全相结合&#xff0c;共同构…

[Python人工智能] 四十六.PyTorch入门 (1)环境搭建、神经网络普及和Torch基础知识

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解合如何利用keras和tensorflow构建基于注意力机制的CNN-BiLSTM-ATT-CRF模型,并实现中文实体识别研究。这篇文章将介绍PyTorch入门知识。前面我们的Python人工智能主要以TensorFlow和Keras为主,…

STM32--IAP程序升级实验

1. STM32程序升级方法 1.1 ST-link / J-link下载 将编译生成的hex文件使用ST-Link/J-Link工具直接下载进 Flash 即可。Keil中点击下载也能一键下载。下载后的代码会存放在Flash的起始地址0x0800 0000处。 简单补充一句&#xff0c;bin文件和hex文件的区别&#xff1a; bin文…

ARM day1练习 求1~100内的和

题目要求:用ARM汇编语言实现1~100之间之和&#xff08;5050 0x13BA&#xff09; .text 声明以下内容是文本段的内容 .global _start .global声明_start标签是一个全局标签_start:mov r1,#0x0 r1 summov r2,#0x1 r2 ifun: 加法函数cmp r2,#100 r2中的值和100作比较add…

Matlab基础篇:数据输入输出

前言 数据输入和输出是 Matlab 数据分析和处理的核心部分。良好的数据输入输出能够提高工作效率&#xff0c;并确保数据处理的准确性。本文将详细介绍 Matlab 数据输入输出的各种方法&#xff0c;包括导入和导出数据、数据处理和数据可视化。 一、导入数据 Matlab 提供了多种方…

Go自定义数据的序列化流程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【计算机毕业设计】167校园失物招领微信小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

导出 S 参数扫描结果供 INTERCONNECT 使用

导出 S 参数扫描结果供 INTERCONNECT 使用 正文正文 有时候,对于 FDTD 无法直接进行仿真的大型仿真链路,我们需要使用 FDTD 针对单个小的模块进行仿真,再将得到的 S 参数结果导入到 INTERCONNECT 中使用,最终完成整个链路的仿真。通常完成 S 参数扫描后其状态如下图所示:…

QT拖放事件之八:通过全局剪切板中的接口QClipboard::mimeData()来获取MIME类型数据

1、演示效果 首先向剪切板写入数据,然后点击paste按钮进行从全局剪切板中 获取 MIME数据。。。 2、核心代码 void Widget::on_pasteBtn_clicked() {const QClipboard* clipBoard = QGuiApplication::clipboard()

非强化学习的对齐方法

在文章《LLM对齐“3H原则”》和《深入理解RLHF技术》中&#xff0c;我们介绍了大语言模型与人类对齐的“3H原则”&#xff0c;以及基于人类反馈的强化学习方法&#xff08;RLHF&#xff09;&#xff0c;本文将继续介绍另外一种非强化学习的对齐方法&#xff1a;直接偏好优化&am…

kafka--发布-订阅消息系统

1. Kafka概述 1. kafka是什么 kafka是分布式的、高并发的、基于发布/订阅模式的消息队列软件系统。 kafka中的重要组件 Producer&#xff1a;消息生产者&#xff0c;发布消息到Kafka集群的终端或服务Consume&#xff1a;消费者&#xff0c;从Kafka集群中消费消息的终端或服…

安达发|生产制造业怎么做好一体化生产计划排产?

在生产制造业中&#xff0c;一体化生产计划排产是确保生产效率和产品质量的关键。要实现这一目标&#xff0c;企业需要采用高级排产软件&#xff08;APS&#xff09;来优化生产流程。以下是如何利用APS软件做好一体化生产计划排产的详细步骤和建议&#xff1a; 1. 需求分析与数…

1.2 DataX 数据同步工具详细教程

DataX 是阿里巴巴开源的一款高效的数据同步工具&#xff0c;旨在实现多种异构数据源之间的高效数据同步。以下是对 DataX 的详细介绍&#xff1a; 架构 DataX 的架构主要包括以下几个核心组件&#xff1a; DataX Core&#xff1a;负责任务调度、插件加载、日志管理等核心功能…

SSM爱心捐赠物资维护系统-计算机毕业设计源码09536

摘要 随着信息技术的快速发展&#xff0c;计算机应用已经进入成千上万的家庭。随着物资数量的增加&#xff0c;物资库存管理也存在许多问题。物资数据的处理量正在迅速增加&#xff0c;原来的手工管理模式不适合这种形式。使用计算机可以完成数据收集、处理和分析&#xff0c;减…

从0搭建一个vue项目,不使用脚手架从html到vue

前言 从最开始学习web网页开始&#xff0c;搭建一个网页只需要创建一个html文件对其进行编写dom标签语言即可&#xff1b;后来分离了html&#xff0c;css和js&#xff0c;搭建一个网页开始需要文件夹&#xff0c;文件夹包含了这3类文件以及静态文件&#xff0c;图片&#xff0c…

常见的跨域场景

我们在解决一个问题的时候应该先去了解这个问题是如何产生的&#xff0c;为什么会有跨域的存在呢&#xff1f;其实&#xff0c;最终的罪魁祸首都是浏览器的同源策略&#xff0c;浏览器的同源策略限制我们只能在相同的协议、IP地址、端口号相同&#xff0c;如果有任何一个不通&a…

【学习笔记】CSS

CSS 1、 基础篇 1.1、选择器 1.2、长度单位 1.3、CSS2 常用属性 1.4、盒模型 1.5、浮动 1.6、定位 position2、 CSS3 2.1、新增长度单位 2.2、新增颜色表示 2.3、新增选择器 2.4、新增盒子属性 2.5、新增背景属性 …