算法设计之动态规划法

article/2025/9/29 19:57:56

算法设计之动态规划法

  • 一、目的
  • 二、内容
    • 1.斐波那契数列
      • ①自底向上
        • 分析
        • 解决
      • ②自顶向下
        • 分析
        • 解决
    • 2.走棋盘问题
        • 分析
        • 解决
    • 3.爬台阶问题
        • 分析
        • 解决
  • 三、反思与总结

一、目的

1.理解动态规划法的特征(多阶段决策\最优子结构\无后效性\子问题重复)
2.理解动态规划法的求解(划分过程\逆向推导\正向计算)
3.掌握动态规划法的简单实体(自顶向下递归备忘\自底向上迭 代填表)和时间复杂度分析

二、内容

1.斐波那契数列

①自底向上

分析

斐波拉契数列的递推式为:
在这里插入图片描述
求第n个斐波拉契数时,需要知道F(n-1)和F(n-2)的值,可以设计一个表格填入n+1个F(n)的值,开始时,根据初始条件可以直接填入F(1)和F(2),然后根据递推式计算出其他元素,表中最后一项就是F(n)的值。
按此想法,计算第n个斐波拉契数,共需循环n次,可能的时间复杂度为O(n)。

解决

算法描述:
输入:n(所求的项数)
输出:第n个斐波拉契数
int Fib(int n)
1.定义一个数组fib[]储存斐波拉契数列,数 组长度为n+1,初始化为0
2.赋值fib[1] = 1,fib[2] = 1
3.定义变量i,循环变量i从3到n执行下列操作:
3.1 fib[i] = fib[i-1] +fib[i-2]
3.2 i++
4.返回fib[n]的值

int Fib(int n){ // 自底向上迭代填表int fib[n+1];fib[1] = 1;fib[2] = 1;for(int i=3; i<=n; i++){fib[i] = fib[i-1] +fib[i-2];}return fib[n];
}

基本语句为fib[i] = fib[i-1] +fib[i-2],执行次数为
在这里插入图片描述

时间复杂度为:O(n)

②自顶向下

分析

在求解第n个斐波拉契数,需要知道F(n-1)和F(n-2)的值,若递归求解,存在子问题重复,降低了算法的效率,所以采用备忘录的方式。使用一个数组充当备忘录,算出某个子问题的解后储存在备忘录中,每次遇到一个子问题先去备忘录中查一查,如果发现已经解决过这个问题了,直接把答案拿出来用,不要再耗时去计算了。

解决

算法描述:
输入:n(所求的项数)
输出:第n个斐波拉契数
int Fib(int n,int fib[])

  1. 如果n=1,fib[1] = 1,返回fib[1]
  2. 如果n=2,fib[2] = 1,返回fib[2]
  3. 否则,执行下列操作
    3.1 如果fib[n]不等于0,返回fib[n]
    3.2 fib[n] = Fib(n-1,fib) + Fib(n-2,fib)
    3.3 返回fib[n]
int Fib(int n,int fib[]){ //自顶向下递归备忘if(n==1){fib[1] = 1;return fib[1];}else if(n==2){fib[2] = 1;return fib[2];}else{if(fib[n]!=0){return fib[n];}}fib[n] = Fib(n-1,fib) + Fib(n-2,fib);return fib[n];
}

在这里插入图片描述
时间复杂度为:
在这里插入图片描述

2.走棋盘问题

分析

求解从棋盘的第一行第一列走到棋盘的第n行第m列的走法,每次只能向右或向下走
逆向推导:最后一步只能向下或向右走,那么走到棋盘的第n行第m列应该是走到棋盘第n行第m-1列的走法和第n-1行第m列走法的和,即f(n-1,m-1)=f(n-2)(m-1)+f(n-1)(m-2),继续向前推,考虑倒数第二步,若走到第一行或者第一列,只能向左或向上倒推,直到f(0,0)
正向求解f(0,0)=0,f(0,1)=1,f(1,0)=1,…,
f(n-1,m-1)=f(n-2)(m-1)+f(n-1)(m-2)得到原问题的解
按此想法,棋盘共有n行m列,可能的时间复杂度为O(mn)

解决

输入:棋盘有n行,m列
输出:每次只能往右走一步,或者往下走一步,从第1行第1列走到第n行m列不同的走法数
int Chess(int n, int m)

  1. 定义一个数组a[ n ][ m ];
  2. 循环变量i从0~n-1时重复执行
    2.1 a[ i ] [ 0 ]= 1;
    2.2 i++;
  3. 循环变量j从0~m-1时重复执行
    3.1 a[ 0 ] [ j ]= 1;
    3.2 j++;
  4. 循环变量i从1~n-1时重复执行下列操作
    4.1循环变量j从0~m-1时重复执行下列操作
    4.1.1 a [ i ][ j ] = a [ i-1 ][ j ] + a [ i ][ j-1 ]
    4.1.2 j++;
    4.2 i++
  5. 返回a [ n-1 ][ m-1 ]的值
int Chess(int n, int m)
{int a[n][m];int i,j;for(int i=0; i<=n-1; i++){a[i][0] = 1;}for(int j=0; j<=m-1; j++){a[0][j] = 1;}for(i=1; i<=n-1; i++){for(j=1; j<=m-1; j++)a[i][j] = a[i-1][j] +a[i][j-1];}return a[n-1][m-1]; 
}

基本语句:a[i][j] = a[i-1][j] +a[i][j-1]
执行次数:
在这里插入图片描述

3.爬台阶问题

分析

要爬到第n级台阶,每次可以跨1级或2级,求解一共有多少种走法逆向推导:最后一步可以跨一级或者两级台阶,那么爬到n级台阶的走法应该是爬n-1级台阶的走法和n-2级台阶走法的和,f(n)=f(n-1)+f(n-2),继续向前推,考虑倒数第二步,直到f(1);
正向求解:f(1)=1,f(2)=2,f(3)=f(1)+f(2)=3,…,f(n)=f(n-1)+f(n-2)得到原问题的解。
按此想法,爬到第n级台阶,共需循环n次,可能的时间复杂度为O(n)

解决

输入:要爬的台阶数 int n
输出:爬完n级台阶的走法
int Chess(int n, int m)

  1. 定义一个数组a[ n ][ m ]
  2. 定义变量i,循环变量i从0到n-1执行下列循环:
    2.1 a[ i ] [ 0 ]= 1
    2.2 i++
  3. 定义变量j,循环变量i从0到m-1执行下列循环:
    3.1 a[ 0 ] [ j ]= 1
    3.2 j++
    4.定义变量i,循环变量i从0到n-1执行下列循环
    4.1循环变量j从0~m-1时重复执行下列操作
    4.1.1 a [ i ][ j ] = a [ i-1 ][ j ] + a [ i ][ j-1 ]
    4.1.2 j++
    4.2 i++
    5.返回a [ n-1 ][ m-1 ]的值
int ClimbStep(int n){int i;int a[n+1] = {0} ;for(i=1; i<=2; i++){a[i]=i;}for(i=3; i<=n; i++){a[i] = a[i-1] +a[i-2];}return a[n];
}

基本语句:a[i] = a[i-1] +a[i-2]
执行次数:
在这里插入图片描述
时间复杂度:O(n)

三、反思与总结

1.如果用分治函数实现斐波那契数列,该函数被调用几次? 而用自顶向下递归备忘实现时,该函数又被调用几次? 自底向上迭代填表时,又被调用几次?请你给出 1 个 n 的具体值,画图回答以上问题。
答:
①分治法(调用 12 次)
在这里插入图片描述
②递归备忘(调用 1 次)
在这里插入图片描述
③迭代填表(调用 5 次)
在这里插入图片描述
2.请从你实现的级别中选择一题,说明动态规划法的解决过程(划分阶段、逆向推导、正向计算),再针对实现说明是自底向上或是自顶向下。
答:
爬台阶(自底向上):
①划分阶段:从第一步依次走到最后一步;
②逆向推导:f(n)=f(n-1)+f(n-2);
③正向计算:f(1)=1;f(2)=1;f(3)=f(1)+f(2)…f(n)=f(n-1)
+f(n-2)
3.你觉得动态规划法和分治法有区别吗?请举例说明。
答:有区别。后者是自顶向下,前者是自底向上解决问题。如实验中对斐波那契数列的两种求解方式。
4.动态规划法的两种实现有区别吗?你觉得动态规划法能解决所有问题吗?
答:有区别。如自底向上迭代法,直接利用递推式,调用一次函数即可求解;而自顶向下备忘法,需要利用递归调用的方式来求解。
动态规划法不能解决所有的问题。适合于用动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的,即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解。

此文章为作者初学算法时的实验,难免存在错误与不足,恳请各位批评与指正。


http://chatgpt.dhexx.cn/article/owLX05MD.shtml

相关文章

【动态规划法】求解TSP问题

问题详情 求解下图所示的TSP问题&#xff0c;计算出所经过的城市编号以及最短路径值&#xff0c;城市代价矩阵如图所示&#xff1a; 求解思路 假设从顶点i出发&#xff0c;令d(i, V’ )表示从顶点i出发经过V’ 中各个顶点一次且仅一次&#xff0c;最后回到出发点&#xff08;…

动态规划法求解0/1背包问题

一、求解0/1背包问题 1、问题描述 有n个重量分别为{w1&#xff0c;w2&#xff0c;…&#xff0c;wn}的物品&#xff0c;它们的价值分别为{v1&#xff0c;v2&#xff0c;…&#xff0c;vn}&#xff0c;给定一个容量为C的背包。 设计从这些物品中选取一部分物品放入该背包的方案&…

动态规划法——多段图的最短路径

目录 动态规划法的基本思想 多段图的基本想法 代码块&#xff08;Java&#xff09; 运行结果 动态规划法的基本思想: 将大问题划分成若干个小问题进行解决&#xff0c;从而一步步获取最优解动归从上到下分析问题&#xff0c;从下到上解决问题动归与分治法相似&#xff0c;其…

强化学习——动态规划法

文章目录 前言一、动态规划法简单认识1.基本概念2.适用情况3.求解步骤4.典型案例二、值函数1.累计折扣奖励2.状态值函数3.动作值函数4.状态值函数与动作值函数的关系5.贝尔曼方程&#xff08;动态规划法核心&#xff09; 三、策略评估1.基于状态值函数评估策略2.基于动作值函数…

南邮|算法分析与设计实验二 动态规划法

目录 实验目的 实验内容 实验步骤 一、最长公共子序列 二、矩阵连乘 实验目的 加深对动态规划法的算法原理及实现过程的理解&#xff0c;学习用动态规划法解决实际应用中的最长公共子序列问题和矩阵连乘问题&#xff0c;体会动态规划法和备忘录方法的异同。 实验内容 …

动态规划--算法

1、动态规划&#xff1a;将求解问题分解成若干个子问题&#xff0c;求解子问题&#xff0c;这些子问题不是独立的 求解后的子问题都会记录到表中&#xff0c;每个子问题仅求解一次&#xff0c; 下次遇到这些子问题直接取解 自底向上的方式计算最优解 2、最优子结构&#xff…

TSP问题,动态规划法

TSP问题是指旅行家要旅行n个城市&#xff0c;要求各个城市经历且仅经历一次然后回到出发城市&#xff0c;并要求所走的路程最短。各个城市间的距离可以用代价矩阵来表示。 假设从顶点i出发&#xff0c;令d(i, V)表示从顶点i出发经过V中各个顶点一次且仅一次&#xff0c;最后…

动态规划法的基本知识

一、动态规划方法相关概念 1、20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时&#xff0c;提出了著名的最优性原理(principle of optimality),同时&#xff0c;把多阶段过程转化为一系列单阶段问题&#xff0c;利用各阶…

动态规划法及其优化

在很多问题中&#xff0c;动态规划算法是我们的最优选择&#xff0c;比起递归算法&#xff0c;动态规划算法的时间复杂度和空间复杂度都更加优越&#xff0c;可以处理的数据规模更大。但是&#xff0c;动态优化算法的时间复杂度为O&#xff08;N*V&#xff09;&#xff0c;也就…

算法设计与分析之动态规划法

文章目录 前言一、动态规划法概述二、动态规划法设计思想三、动态规划法的基本要素四、动态规划算法的设计步骤五、动态规划法与分治法六、动态规划法与贪心法七、动态规划法示例总结 前言 大家好&#xff0c;我是一只勤勤恳恳的程序猿。本篇文章小猿将跟您分享算法设计与分析中…

算法-动态规划法

动态规划是在20世纪50年代由美国数学家贝尔曼为研究最优控制问题而提出的&#xff0c;当该方法在应用数学中的价值被大家认同以后&#xff0c;在计算机学界&#xff0c;动态规划法成为一种通用的算法设计技术用来求解多阶段决策最优化问题。 所以&#xff0c;同学们&#xff0…

动态规划算法

一 动态规划算法 动态规划(Dynamic Programming)算法的核心思想是&#xff1a;将大问题划分为小问题进行解决&#xff0c;从而一步步获取最优解的处理算法。 动态规划算法与分治算法类似。其基本思想也是将待求解问题分解成若干个子问题&#xff0c;先求解子问题&#xff0c;…

经典中的经典算法:动态规划(详细解释,从入门到实践,逐步讲解)

动态规划的重要性就不多说,直接进入正题 首先,我们看一下官方定义:定义: 动态规划算法是通过拆分问题&#xff0c;定义问题状态和状态之间的关系&#xff0c;使得问题能够以递推&#xff08;或者说分治&#xff09;的方式去解决。 动态规划算法的基本思想与分治法类似&#xf…

目标检测中的多尺度特征结合方式

目录 简述 解构物体检测各个阶段 FPN的演进 1&#xff09;无融合 2&#xff09;自上而下单向融合 a&#xff09;Faster/Master/Cascade RCNN中的FPN b&#xff09;RetinaNet中的FPN c&#xff09;Yolov3中的FPN 3&#xff09;简单双向融合 4&#xff09;复杂的双向融…

总结-CNN中的目标多尺度处理

Fly-AI竞赛服务平台 flyai.com 在开始学习之前推荐大家可以多在 FlyAI竞赛服务平台多参加训练和竞赛&#xff0c;以此来提升自己的能力。FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台。每周免费提供项目开源算法样例&#xff0c;支持算法能力变现以及快…

【MFEN:轻量级多尺度特征提取:SR网络】

MFEN: Lightweight multi-scale feature extraction super-resolution network in embedded system &#xff08;MFEN&#xff1a;嵌入式轻量级多尺度特征提取超分辨率网络&#xff09; 深度卷积神经网络&#xff08;CNN&#xff09;在超分辨率&#xff08;SR&#xff09;方面…

深度学习笔记---多尺度网络结构归类总结

目录 1.什么是图像金字塔 1.1 高斯金字塔 ( Gaussian pyramid): 1.2 拉普拉斯金字塔&#xff08;Laplacian pyramid&#xff09; 1.3 DOG金字塔 2. 多尺度网络&#xff08;MTCNN&#xff09; 2.1 多尺度输入网络 2.2 多尺度特征融合网络 2.2.1 并行多分支网络 2.2.2 串行…

【边缘注意:深度多尺度特征】

Learning a Deep Multi-Scale Feature Ensemble and an Edge-Attention Guidance for Image Fusion &#xff08;学习深度多尺度特征集成和图像融合的边缘注意指南&#xff09; 在本文中&#xff0c;我们提出了一种用于红外和可见光图像融合的深度网络&#xff0c;该网络将具…

多尺度特征的提取

1、图像金字塔 将图片进行不同尺度的缩放&#xff0c;得到图像金字塔&#xff0c;然后对每层图片提取不同尺度的特征&#xff0c;得到特征图。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低&#xff0c;且来源于同一张原始图的图像集合。其通过梯次向下采样获得&…

MSRN(多尺度超分辨率重建)

目前的研究倾向于使用更深层次的卷积神经网络来提高性能。然而,盲目增加网络深度不能有效改善网络。更糟糕的是,随着网络深度的增加,训练过程中出现了更多的问题,需要更多的训练技巧。在本文中,我们提出了一种新颖的多尺度残差网络 (MSRN) 来充分利用图像特征,该网络优于…