#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] = 1
  FOR i = 2 TO n
      F[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 m
    c[i][0] = 0
  FOR j = 1 TO n
    c[0][j] = 0
  FOR i = 1 TO m
    FOR j = 1 TO n
      IF X[i] == Y[j]
        c[i][j] = c[i-1][j-1] + 1
        b[i][j] = 1
      ELSE IF c[i-1][j] >= c[i][j-1]      //暗指x[i]!=y[j]  
        c[i][j] = c[i-1][j] 
        b[i][j] = 3
      ELSE
        c[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 
    RETURN
  IF b[i][j] == 1
    LCS-PRINT(b,X,i-1,j-1)
    PRINT X[i]
  ELSE IF b[i][j] == 3
    LCS-PRINT(b,X,i-1,j)
  ELSE
    LCS-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 0
  IF X[i] == Y[j]
    PRINT X[i] 
    RETURN LCS-REC(X,Y,i-1,j-1,c,b) + 1 
  ELSE
    RETURN 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 == j
    m[i,j] = 0, s[i,j] = 0
	  RETURN
  m[i,j] = ∞
  FOR k = i TO j-1
    q = RECURSIVE-MATRIX-CHAIN(p,i,k,m,s)
      + RECURSIVE-MATRIX-CHAIN(p,k+1,j,m,s)
      + pi-1pkpj
      IF q < m[i,j]
      m[i,j] = q
      s[i,j] = k
  RETURN 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 n
    m[i,i] = 0
  FOR l = 2 TO n //l为链的长度
    FOR i = 0 TO n-l+1
      j = i+l-1
      m[i,j] = ∞
      FOR k = i TO j-1
        q = m[i,k] + m[k+1,j] + pi-1pkpj
        IF q < m[i,j]
	        m[i,j] = q
          s[i,j] = k
  RETURN 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 n
    m[i,i] = 0
  FOR l = 2 TO n //l为链的长度
    FOR i = 0 TO n-l+1
      j = i+l-1
      m[i,j] = ∞
      FOR k = i TO j-1
        q = m[i,k] + m[k+1,j] + pi-1pkpj
        IF q < m[i,j]
	        m[i,j] = q
          s[i,j] = k
  RETURN 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 n
    C[i,0] = 0
  FOR j = 1 TO W                   //可用容量
    C[0,j] = 0
  FOR i = 1 TO n
    FOR j = 1 TO W
      IF j < w[i]
        C[i,j] = C[i-1][j]         //装不下第i个物品
      ELSE
        C[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 – 1
  j = W                              //可用容量
  FOR i = n TO 1
    IF 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和w
  n = w.length
  //x[1..n]为最优值,存放已选物品的相应重量。各元素初始化为0
  wRemained = W           //剩余重量是W
  FOR i = 1 TO n          
    IF wRemained <= 0       //无剩余重量 
      BREAK;
    ELSE IF wRemained >= w[i]   
      x[i] = 1            //存入
      wRemained = W – w[i]
    ELSE
      x[i] = 0            //不存入
      BREAK
  RETURN x

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Jetpack架构组件_Navigaiton组件_1.Navigaiton切换Fragment

1.Navigation主要作用 方便管理Fragment &#xff08;1&#xff09;方便我们管理Fragment页面的切换 &#xff08;2&#xff09;可视化的页面导航图&#xff0c;便于理清页面间的关系。 &#xff08;3&#xff09;通过destination和action完成页面间的导航 &#xff08;4&a…

基于Java+MySQL停车场车位管理系统详细设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

SSL证书类型解析:DV、OV、EV证书的区别与适用场景

在互联网时代&#xff0c;数据安全和用户隐私保护变得尤为重要。SSL证书作为加密网站通信的主要工具&#xff0c;为用户提供了一个安全的浏览环境。然而&#xff0c;面对市场上多种类型的SSL证书&#xff0c;许多网站所有者常常感到困惑。本文将重点解析三种常见的SSL证书类型—…

第二证券:突然飙升!涨超10%!“躺赚”机会又来

接近2024年上半年底&#xff0c;国债逆回购操作的“窗口期”或正在到来&#xff0c;相关国债逆回购的利率有望呈现飙升。 就在今天上午&#xff0c;沪深买卖所3天期国债逆回购利率已呈现大幅上涨&#xff0c;盘中最大涨幅均超过了10%。 国债逆回购操作“窗口期”或正在到来 …

TDengine 推出新连接器,与 Wonderware Historian 无缝连接

在最新发布的TDengine 3.2.3.0 版本中&#xff0c;我们进一步更新了 TDengine 的数据接入功能&#xff0c;推出了一款新的连接器&#xff0c;旨在实现 Wonderware Historian&#xff08;现称为 AVEVA Historian&#xff09;与 TDengine 的集成。这一更新提供了更加便捷和高效的…

Appium+python自动化(二十五)- 那些让人抓耳挠腮、揪头发和掉头发的事 - 获取控件ID(超详解)

简介 在前边的第二十二篇文章里&#xff0c;已经分享了通过获取控件的坐标点来获取点击事件的所需要的点击位置&#xff0c;那么还有没有其他方法来获取控件点击事件所需要的点击位置呢&#xff1f;答案是&#xff1a;Yes&#xff01;因为在不同的大小屏幕的手机上获取控件的坐…

零基础STM32单片机编程入门(三)中断详解及按键中断实战含源码视频

文章目录 一.概要二.可嵌套的向量中断控制器 (NVIC)三.中断向量表四.中断优先级详解五.STM32外部中断控制器(EXTI)1.EXTI简介2.EXTI在中断向量表的位置3.EXTI外部中断产生的信号流向4.EXTI中断产生后的中断服务程序 六.CubeMX配置一个GPIO输入中断的例程七.CubeMX工程源代码下载…

四步轻松搞定!探索字节最新AnimateDiff-Lightning:高质量视频生成的秘密武器!

字节前脚刚发布了文生图大模型 SDXL-Lightning&#xff0c;后脚就又对文生视频领域下手了。 就在这几天又推出了文生视频模型&#xff1a;AnimateDiff-Lightning&#xff0c;它是一种快速的文本到视频生成模型。它生成视频的速度比原始 AnimateDiff 快十倍以上&#xff0c;只需…

二、大模型原理(Transformer )

Transformer是一种基于自注意力机制&#xff08;Self-Attention Mechanism&#xff09;的深度学习模型&#xff0c;它在2017年由Vaswani等人在论文《Attention Is All You Need》中提出。Transformer模型的出现极大地推动了自然语言处理&#xff08;NLP&#xff09;领域的发展&…

浏览器扩展V3开发系列之 chrome.cookies 的用法和案例

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 chrome.cookies API能够让我们在扩展程序中去操作浏览器的cookies。 在使用 chrome.cookies 要先声明…

IDEA中使用leetcode 刷题

目录 1.IDEA下载leetcode插件 2.侧边点开插件 3.打开网页版登录找到cookie复制 4.回到IDEA登录 5.刷题 6.共勉 1.IDEA下载leetcode插件 2.侧边点开插件 3.打开网页版登录找到cookie复制 4.回到IDEA登录 5.刷题 6.共勉 算法题来了不畏惧&#xff0c; 挑战前行是成长的舞台…

中文检测程序(静态代码扫描)

欢迎您关注我们&#xff0c;经常分享有关Android出海&#xff0c;iOS出海&#xff0c;App市场政策实时更新&#xff0c;互金市场投放策略&#xff0c;最新互金新闻资讯等文章&#xff0c;期待与您共航世界之海。 在前些日子&#xff0c;给大家安利了我们在用的AS中文实时检测插…

服务器数据恢复—用raid6阵列磁盘组建raid5阵列如何恢复原raid数据?

服务器存储数据恢复环境&#xff1a; 华为OceanStor 5800存储&#xff0c;该存储中有一组由10块硬盘组建的raid6磁盘阵列&#xff0c;供企业内部使用&#xff0c;服务器安装linux操作系统EXT3文件系统&#xff0c;划分2个lun。 服务器存储故障&#xff1a; 管理员发现存储中rai…

Flask之表单

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 目录 一、HTML表单 二、使用Flask-WTF处理表单 2.1、定义WTForms表单类 2.2、输出HTML代码 2.3、在模板中渲染表单 三、处理表单数据 3.1、提…

【数据结构与算法】静态查找表(顺序查找,折半查找,分块查找)详解

顺序查找、折半查找、分块查找算法适合的场合。 顺序查找&#xff1a;顺序存储或链式存储的静态查找表均可。 折半查找&#xff08;二分查找&#xff09;&#xff1a;采用顺序存储结构的有序表。 分块查找&#xff08;索引顺序查找 &#xff09;&#xff1a;分块有序表。 …

项目管理计划(DOC原件)

本文档为XXX系统项目管理计划&#xff0c;本计划的主要目的是通过本方案明确本项目的项目管理体系。方案的主要内容包括&#xff1a;明确项目的目标及工作范围&#xff0c;明确项目的组织结构和人员分工&#xff0c;确立项目的沟通环境&#xff0c;确立项目进度管理方法&#x…

【ai】trition:tritonclient yolov4:部署ubuntu18.04成功

X:\05_trition_yolov4_clients\01-python server代码在115上,client本想在windows上, 【ai】trition:tritonclient.utils.shared_memory 仅支持linux 看起来要分离。 client代码远程部署在ubuntu18.04上 ubuntu18.04 创建yolov4-trition python=3.7 环境 (base) zhangbin@ub…

MCU复位时GPIO是什么状态?

大家一定遇到过上电或者复位时外部的MOS电路或者芯片使能信号意外开启&#xff0c;至此有经验的工程师就会经常关心一个问题&#xff0c;MCU复位时GPIO是什么状态&#xff1f;什么电路需要外部加上下拉&#xff1f; MCU从上电到启动&#xff0c;实际可分为复位前和复位后、初始…

uniapp - 微信小程序 - 自定义底部tabbar

废话不多说&#xff0c;直接行源码 这里需要的底部tabbar的图片在这里 我的资源里面呢 图片是这样的 先看成品吧 首先 - BaseApp\components\Tabbar.vue <script setup>import {ref,nextTick,watch} from "vue"// 核心 - 隐藏uniapp自带的底部tabbaruni.hi…

Python爬虫实战:利用代理IP批量下载哔哩哔哩美女视频

文章 目录 1.前言2.爬取目标3.准备工作3.1 环境安装3.2 代理免费获取 四、爬虫实战分析4.1 翻页分析4.2 获取视频跳转链接4.3 下载视频4.4 视频音频合并4.5 完整源码 五、总结 1.前言 粉丝们&#xff08;lsp&#xff09;期待已久的Python批量下载哔哩哔哩美女视频教程它终于来…