1 递归函数建模

动态规划一般用于全局问题,在构造递归的时候,一般采用自顶向下分解的方法,先把全局问题分解成更小的子问题求解。下面举两个例子

例子1:有一座高度是10阶的楼梯,从下往上走,每跨一步可以是一级或两级台阶。要求用程序求出一共一共有多少种走法。

问题分析建模:首先总共有10步,假设只剩最后一步就到达第10阶,这个时候会有两种情况:第一种是从第九阶到第十阶,第二种是从第八阶到第十阶,然后两种情况里面如何从第一个阶梯走到第九阶,从第一个阶梯走到第八阶。也就是我们可以构造出最后一步的函数:

f(10)=f(9)+f(8)

这个时候我们就可以构造出递归函数:

f(n)=f(n-1)+f(n-2)

写成通用一点的公式,也就是用for循环遍历最后一次的情况:

f(n)=sum(f(n-j)) 且j=1,2

因此我们只要知道初始值f(1)、f(2)就可以求解f(10)。这种我们称之为一维动态规划。

例子2:给定一个m*n矩阵A,从左上角开始每次只能向右走或者向下走,最后达到右下角的位置,路径中所有数字累加起来就是路径和,返回所有路径的最小路径和,如果给定的矩阵如下,那么路径1,3,1,0,6,1,0就是最小路径和,返回12。

1 3 5 9

8 1 3 4

5 0 6 1

8 8 4 0

问题分析建模:对于这个题目,假设m是m行n列的矩阵,那么我们用dist[m][n]来抽象这个问题,dist[i][j]表示的是从原点到i,j位置的最短路径和。我们要求解的是dist[m][n]的最大值,然而其实最后一步dist[m][n]又可以分解成两种情况,从dist[m-1][n]往下走;从dist[m][n-1]往右走,取这两种情况的最小值,那么我们就可以列出方程:

dist[m][n]=min(dist[m-1][n]+A[m][n],dist[m][n-1]+A[m][n])

抽取出A[m][n],该方程可以进一步写成:

dist[m][n]=A[m][n]+min(dist[m-1][n],dist[m][n-1])

因此接着我们只需要根据初始条件,就可以求解,初始条件dist[0][0]=1。这个例子又称之为二维动态规划。

2动态规划

(1)自顶向下递归

其主要原理是加入备忘录,用于记录之前已经记录过的函数值,比如在写例子1递归函数:

f(n)=f(n-1)+f(n-2)

代码的时候,用一个数组记录一下f(i),然后在写递归函数的时候,遇到f(i)的值如果已经被计算过一次了,那么就不用继续计算了;如果还没有被记录,那么就保存一下f(i)。

在写例子2递归函数的时候,用二维的数组f[m][n]记录一下已经计算过的函数值

(2)自底向上迭代

从0开始往上迭代,比如对于例子1,先求:

f[2]=f[1]+f[0]

f[3]=f[2]+f[1]

f[4]=f[3]+f[3]

直到迭代到f[10]为止。

3 示例源码

#include <istream>;
#include <vector>;
#include <math.h>
using namespace std;
int A[4][4] = {1,3,5,9,8,1,3,4,5,0,6,1,8,8,4,0};
int f[4][4]={0};//备忘录
int count=0;//统一一下采用备忘录的时候,减少的计算次数
int function_top2bottom(int m,int n){//自顶向下递归if (f[m][n]>0)return f[m][n];count++;int min_dist=0;if(m==0&&n==0){min_dist=0;}else if (m-1>=0&&n==0)min_dist=function_top2bottom(m-1,n);else if (m==0&&n-1>=0) {min_dist=function_top2bottom(m,n-1);}else {min_dist=min(function_top2bottom(m,n-1),function_top2bottom(m-1,n));}f[m][n]=min_dist+A[m][n];return f[m][n];
}int function_bottom2top(int m,int n){//自底向下迭代for (int i = 0; i < m; ++i) {for (int j = 0; j <n ; ++j) {int min_dist=0;if(m==0&&n==0){min_dist=0;}else if (m-1>=0&&n==0)min_dist=f[m-1][n];else if (m==0&&n-1>=0) {min_dist=f[m][n-1];}else {min_dist=min(f[m-1][n],f[m][n-1]);}f[m][n]=min_dist+A[m][n];}}return f[m][n];
}void dynamic_programming()
{std::cout<<function_top2bottom(3,3)<<std::endl;std::cout<<count<<std::endl;//可以测试一下,自顶向下递归的时候,少用备忘录的count值std::cout<<function_bottom2top(3,3)<<std::endl;}

数据结构(十二)动态规划相关推荐

  1. 数据结构(十二) -- 树(四) -- 霍夫曼树

    1. 基本介绍 给定n个权值为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也成为了霍夫曼树. 霍夫曼树是带权路径长度最短的树,权值较大的节点离根较 ...

  2. OpenCV学习笔记(四十一)——再看基础数据结构core OpenCV学习笔记(四十二)——Mat数据操作之普通青年、文艺青年、暴力青年 OpenCV学习笔记(四十三)——存取像素值操作汇总co

    OpenCV学习笔记(四十一)--再看基础数据结构core 记得我在OpenCV学习笔记(四)--新版本的数据结构core里面讲过新版本的数据结构了,可是我再看这部分的时候,我发现我当时实在是看得太马 ...

  3. 【Java数据结构与算法】第十八章 动态规划和KMP算法

    第十八章 动态规划和KMP算法 文章目录 第十八章 动态规划和KMP算法 一.动态规划 1.介绍 1.爬楼问题 2.扔鸡蛋问题 3.背包问题 二.KMP算法 1.引入 2.介绍 2.代码实现 一.动态 ...

  4. Android版数据结构与算法汇总十二章

    Android版数据结构与算法(一):基础简介 https://www.cnblogs.com/leipDao/p/9140726.html Android版数据结构与算法(二):基于数组的实现Arr ...

  5. 【BZOJ5498】[十二省联考2019]皮配(动态规划)

    [BZOJ5498][十二省联考2019]皮配(动态规划) 题面 BZOJ 洛谷 题解 先考虑暴力\(dp\),设\(f[i][j][k]\)表示前\(i\)所学校,有\(j\)人在某个阵营,有\(k ...

  6. 12_JavaScript数据结构与算法(十二)二叉树

    JavaScript 数据结构与算法(十二)二叉树 二叉树 二叉树的概念 如果树中的每一个节点最多只能由两个子节点,这样的树就称为二叉树: 二叉树的组成 二叉树可以为空,也就是没有节点: 若二叉树不为 ...

  7. 静态树表查找算法及C语言实现,数据结构算法C语言实现(三十二)--- 9.1静态查找表...

    一.简述 静态查找表又分为顺序表.有序表.静态树表和索引表.以下只是算法的简单实现及测试,不涉及性能分析. 二.头文件 /** author:zhaoyu date:2016-7-12 */ #inc ...

  8. 【Java数据结构与算法】第十二章 哈夫曼树和哈夫曼编码

    第十二章 哈夫曼树和哈夫曼编码 文章目录 第十二章 哈夫曼树和哈夫曼编码 一.哈夫曼树 1.基本术语 2.构建思路 3.代码实现 三.哈夫曼编码 1.引入 2.介绍 3.代码实现哈夫曼编码综合案例 一 ...

  9. 数据结构思维 第十二章 `TreeMap`

    第十二章 TreeMap 原文:Chapter 12 TreeMap 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 这一章展示了二叉搜索树,它是个Map接口的高效实现.如果我们 ...

最新文章

  1. Java获取游戏头像_java爬取堆糖所有头像(高质量版头像)
  2. sftp连不上服务器 vscode_VSCODE 【SFTP】 Code:3221225477 / 扩展宿主意外终止 解决方法...
  3. 34岁,外企倒闭成功上岸大厂,50K,附面试秘籍
  4. 作业03:格式化输出
  5. shell 字符串截取
  6. Edge X Kubernetes Meetup,探索云原生新边界
  7. 高速缓冲存储器的功能、结构与工作原理
  8. JS中的数据类型转换
  9. 实例61:python
  10. html怎么给变量添加样式,通过CSS变量修改样式
  11. linux c语言变量地址类型,C语言基础知识:访问内存地址的方法
  12. Java EE开发四大常用框架(1)
  13. excel取末尾数字_excel取后面几位数
  14. LSI阵列卡的使用教程
  15. 在cmd中编译C语言方法
  16. Because we are OIer
  17. 我爱赚钱吧:建网站也是可以赚钱的③
  18. 每个系统管理员都要知道的 30 个 Linux 系统监控工具
  19. javascript入门及基础语法结构
  20. 【读书笔记】《博弈论》

热门文章

  1. 每次请求刷新token的时间
  2. fit函数 model_深度学习与Tensorflow学习笔记2 ——回调函数callbacks和Tensorboard
  3. vscode+TCC快捷编译c语言
  4. 《Linux命令行与shell脚本编程大全 第3版》高级Shell脚本编程---24
  5. Alpha冲刺报告(8/12)(麻瓜制造者)
  6. Codeforces Codeforces Round #383 (Div. 2) E (DFS染色)
  7. UIButton和UIimageView
  8. Windows下配置Mysql免安装版
  9. 2012年12月21日所谓世界末日时做的第一个五年规划——成为领域内的专家
  10. 和谐社区,和谐技术:微软的宠儿们,为什么富人的孩子就不能早当家?