#03动态规划

news2024/7/6 18:28:17

要点:

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

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

动态规划方法的应用。

难点:

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


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

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.coloradmin.cn/o/1861938.html

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

相关文章

使用Servlet开发javaweb,请求常见错误详解及其解决办法【404、405、500】

Servlet报错的情况多种多样&#xff0c;涵盖了配置错误、代码逻辑错误、资源未找到、权限问题等多个方面。以下是一些常见的Servlet报错情况及其可能的原因和解决方法&#xff1a; 404 Not Found: 错误原因图示&#xff1a; URL映射 发送请求&#xff0c;出现404错误 原因: 请…

excel隐藏的部分内容如何显示出来?3个方法帮助你!

excel隐藏的部分如何显示出来&#xff1f;你是否曾经在Excel中遇到过某些单元格被隐藏&#xff0c;或者某些数据在编辑时突然消失&#xff0c;让你感到困惑和无助&#xff1f;不要担心&#xff0c;今天我将向你揭示如何解决这些问题&#xff0c;让你轻松显示隐藏的部分。 方法1…

神经网路学习7-线性模型

一个最简单的线性模型&#xff0c;w是权重&#xff0c;一般来说会取随机值&#xff0c;然后不断学习直到与预期相同 如此以此取每个值与真实值的差值&#xff0c;即评估误差 即找一个合适的权重w&#xff0c;使得平均误差最小 上面的是针对单个样本的&#xff0c;后面的是对…

onnx模型修改:去掉Dropout层

文章目录 尝试1&#xff1a;强行设置dropout层train mode为False尝试2&#xff1a;找到onnx模型中的dropout, train mode设置为False尝试3&#xff1a;直接删除dropout层&#xff0c;连接其输入输出结语 最近训练模型使用了tinyvit&#xff0c;性能挺强的&#xff1a; 但是导出…

Posix消息队列使用总结

Posix在线文档&#xff1a; The Single UNIX Specification, Version 2 (opengroup.org) Linux系统中提供了两种不同接口的消息队列&#xff1a; POSIX消息队列。POSIX为可移植的操作系统接口。System V消息队列。System V 是 AT&T 的第一个商业UNIX版本(UNIX System III)的…

【Mac】iTerm for mac(终端工具)软件介绍及安装教程

软件介绍 iTerm 是 macOS 上一个非常受欢迎的终端仿真器&#xff0c;提供了比默认的 Terminal 应用更多的功能和定制选项。它是一款开源软件&#xff0c;主要用于命令行界面的操作和开发者工具。 主要特点和功能&#xff1a; 分页和标签&#xff1a; iTerm 允许用户在单个窗…

Spring Boot项目的两种发布方式

5.1.方式1&#xff1a;通过jar包发布 步骤1&#xff1a;在pom中添加一个SpringBoot的构建的插件 <build><plugins><plugin><groupId>org.springframework.boot</groupId><!--自动检测项目中的 main 函数--><artifactId>spring-boot…

开发一款直播APP完整指南

直播是一种强大的营销工具&#xff0c;可以让企业与观众进行真实的互动。 根据Grand View Research发布的预测&#xff0c;直播行业规模将从 2021 年的 700 亿美元增长到 2028 年的近 2240 亿美元&#xff0c;七年内增长三倍。 区块链技术和人工智能等技术进步将在未来几年提…

mybatis-plus 实体中空字段更新不上

FieldStrategy 是一个枚举类型&#xff0c;它定义了字段的几种策略&#xff1a; IGNORED&#xff1a;忽略判断&#xff0c;所有字段都进行更新操作 NOT_NULL&#xff1a;非 NULL 判断&#xff08;默认策略&#xff09;&#xff0c;字段非 NULL 才进行更新 NOT_EMPTY&#xff…

数据结构与算法—空间复杂度详解与示例(C#,C++)

文章目录 1. 数据结构概述2. 空间复杂度的定义及影响因素3. 空间复杂度的区分常数空间复杂度&#xff08;O(1)&#xff09;线性空间复杂度&#xff08;O(n)&#xff09;其他空间复杂度 4. 几种典型数据结构的优缺点分析数组&#xff08;Array&#xff09;链表&#xff08;Linke…

专业解析U盘数据恢复:方法、方案与常见问答

一、U盘数据恢复概述 在信息化社会&#xff0c;U盘作为一种便捷的数据存储介质&#xff0c;广泛应用于各种场合。然而&#xff0c;由于其体积小、易携带的特点&#xff0c;U盘数据丢失的风险也随之增加。U盘数据恢复&#xff0c;即是指通过技术手段&#xff0c;将因各种原因导…

【Spine学习16】之 人物面部绑定

1、创建头部骨骼 一根头骨 以头骨为父结点创建一个面部控制器face-holder 2、创建头发和face面部控制结点的变换约束 左右头发的约束指向为face结点 3、设定后发的变换约束&#xff0c;约束指向为face结点&#xff0c;反方向移动 设置参数为-100 同理&#xff0c;耳朵也依…

pytest测试框架pytest-html插件生成HTML格式测试报告

Pytest提供了丰富的插件来扩展其功能&#xff0c;pytest-html插件帮助我们生成HTML格式的测试报告&#xff0c;为我们提供直观、有效的测试结果展示。 为了使用 pytest-html&#xff0c;需要满足以下条件&#xff1a; Python 3.6 或更高版本 pytest-html安装 使用pip命令安…

Kubernetes Prometheus 系例 | kubernetes 部署 Kafka exporter监控Kafka集群

prometheus 监控 kafka 常见的有两种开源方案&#xff1b; 部署 exporter 或 jmx 配置监控。 项目地址&#xff1a; kafka_exporter&#xff1a;https://github.com/danielqsj/kafka_exporter jmx_exporter&#xff1a;https://github.com/prometheus/jmx_exporter 本文采用kaf…

Java宝藏实验资源库(5)字符流

一、实验目的 掌握输入输出流的基本概念。掌握字符流处理类的基本结构。掌握使用字符流进行输入输出的基本方法。 二、实验内容、过程及结果 **12.12 (Reformat Java source code) Write a program that converts the Java source code from the next-line brace style to…

Reactor模型:网络线程模型演进

一&#xff0c;阻塞IO线程池模型&#xff08;BIO&#xff09; 这是传统的网络编程方案所采用的线程模型。 即有一个主循环&#xff0c;socket.accept阻塞等待&#xff0c;当建立连接后&#xff0c;创建新的线程/从线程池中取一个&#xff0c;把该socket连接交由新线程全权处理。…

HarmonyOS NEXT Developer Beta1配套相关说明

一、版本概述 2024华为开发者大会&#xff0c;HarmonyOS NEXT终于在万千开发者的期待下从幕后走向台前。 HarmonyOS NEXT采用全新升级的系统架构&#xff0c;贯穿HarmonyOS全场景体验的底层优化&#xff0c;系统更流畅&#xff0c;隐私安全能力更强大&#xff0c;将给您带来更高…

qmt量化交易策略小白学习笔记第44期【qmt编程之期货行情数据】

qmt编程之获取期货行情数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 获取行情数据 提示 使用该接口时&#xff0c;需要先订阅实时行情(subscribe_quote)或下载过历史行情(download_hi…

WEB界面上使用ChatGPT

&#xff08;作者&#xff1a;陈玓玏&#xff09; 开源项目&#xff0c;欢迎star哦&#xff0c;https://github.com/tencentmusic/cube-studio 随着大模型不断发展&#xff0c;现在无论写代码&#xff0c;做设计&#xff0c;甚至老师备课、评卷都可以通过AI大模型来实现了&…

5分钟带你部署一套Jenkins持续集成环境​

5分钟带你部署一套Jenkins持续集成环境 Jenkins是开源CI&CD软件领导者&#xff0c; 提供超过1000个插件来支持构建、部署、自动化&#xff0c; 满足任何项目的需要。 Jenkins的优点 持续集成和持续交付 作为一个可扩展的自动化服务器&#xff0c;Jenkins 可以用作简单的 CI…