什么是动态规划,我们要如何描述它?

动态规划算法通常基于一个递推公式及一个或多个初始状态。当前子问题的解将由上一次子问题的解推出。使用动态规划来解题只需要多项式时间复杂度,因此它比回溯法、暴力法等要快许多。

这里所说的子问题并不一定指前一个问题的解

比如说1+2+3+。。。+100,我们这里可以sum[i]+100来求出总和,而sum[i]是1加到i的总和,这个问题就是1加到99的子问题再加上100就得到。

动态规划则并非是如此,它可能跟前面所有的子问题的某个解有联系,举个例子:

如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?

(表面上这道题可以用贪心算法,但贪心算法无法保证可以求出解,比如1元换成2元的时候)

首先我们思考一个问题,如何用最少的硬币凑够i元(i<11)?为什么要这么问呢?两个原因:1.当我们遇到一个大问题时,总是习惯把问题的 规模变小,这样便于分析讨论。 2.这个规模变小后的问题和原来的问题是同质的,除了规模变小,其它的都是一样的,本质上它还是同一个问题(规模变小后的问题其实是原问题的子问题)。

好了,让我们从最小的i开始吧。当i=0,即我们需要多少个硬币来凑够0元。由于1,3,5都大于0,即没有比0小的币值,因此凑够0元我们最少需 要0个硬币。 (这个分析很傻是不是?别着急,这个思路有利于我们理清动态规划究竟在做些什么。) 这时候我们发现用一个标记来表示这句“凑够0元我们最少需要0个硬币。”会比较方便,如果一直用纯文字来表述,不出一会儿你就会觉得很绕了。那么,我们用 d(i)=j来表示凑够i元最少需要j个硬币。于是我们已经得到了d(0)=0,表示凑够0元最小需要0个硬币。当i=1时,只有面值为1元的硬币可用, 因此我们拿起一个面值为1的硬币,接下来只需要凑够0元即可,而这个是已经知道答案的,即d(0)=0。所 以,d(1)=d(1-1)+1=d(0)+1=0+1=1。当i=2时,仍然只有面值为1的硬币可用,于是我拿起一个面值为1的硬币,接下来我只需要再 凑够2-1=1元即可(记得要用最小的硬币数量),而这个答案也已经知道了。所以d(2)=d(2-1)+1=d(1)+1=1+1=2。一直到这里,你 都可能会觉得,好无聊,感觉像做小学生的题目似的。因为我们一直都只能操作面值为1的硬币!耐心点,让我们看看i=3时的情况。当i=3时,我们能用的硬 币就有两种了:1元的和3元的( 5元的仍然没用,因为你需要凑的数目是3元!5元太多了亲)。既然能用的硬币有两种,我就有两种方案。如果我拿了一个1元的硬币,我的目标就变为了:凑够 3-1=2元需要的最少硬币数量。即d(3)=d(3-1)+1=d(2)+1=2+1=3。这个方案说的是,我拿3个1元的硬币;第二种方案是我拿起一 个3元的硬币,我的目标就变成:凑够3-3=0元需要的最少硬币数量。即d(3)=d(3-3)+1=d(0)+1=0+1=1. 这个方案说的是,我拿1个3元的硬币,这里d(3)值跟d(2)是没有关系的,如果你还不理解,下面我们结合01背包来说明。好了,这两种方案哪种更优呢?记得我们可是要用最少的硬币数量来凑够3元的。所以,选择d(3)=1,怎么来的呢? 具体是这样得到的:d(3)=min{d(3-1)+1, d(3-3)+1}。

状态和状态转移方程

从以上的文字中,我们要抽出动态规划里非常重要的两个概念:状态和状态转移方程。

状态:就是上面d(3)d(2)等,抽象d(i);

状态转移方程:d(3)=min{d(3-1)+1, d(3-3)+1},抽象d(i)=min{ d(i-vj)+1 },其中i-vj >=0,vj表示第j个硬币的面值;

【动态规划】关于转移方程的简单理解相关推荐

  1. 动态规划中转移方程的一个技巧

    动态规划是一个很神奇的东西,总结一下自己写动态规划是的一些盲区! 有时候在定义状态的时候,可以用一定的方法,可以达到对转移时的时间复杂度起到很大的优化作用,以下面的题目来说明这点. Writing C ...

  2. 一直学不明白的「递归」与「动态规划」原来这么简单

    在学习「数据结构和算法」的过程中,因为人习惯了平铺直叙的思维方式,所以「递归」与「动态规划」这种带循环概念(绕来绕去)的往往是相对比较难以理解的两个抽象知识点. 程序员小吴打算使用动画的形式来帮助理解 ...

  3. android 点击事件消费,Android View事件分发和消费源码简单理解

    Android View事件分发和消费源码简单理解 前言: 开发过程中觉得View事件这块是特别烧脑的,看了好久,才自认为看明白.中间上网查了下singwhatiwanna粉丝的读书笔记,有种茅塞顿开 ...

  4. 【转载】Deep learning:十九(RBM简单理解)

    Deep learning:十九(RBM简单理解) 这篇博客主要用来简单介绍下RBM网络,因为deep learning中的一个重要网络结构DBN就可以由RBM网络叠加而成,所以对RBM的理解有利于我 ...

  5. 学习:双机热备、集群、负载均衡、SQL故障转移群集简单理解(转)

    双机热备.集群.负载均衡.SQL故障转移群集简单理解平常,大家常提到几个技术名词:双机热备.集群.负载均衡.SQL故障转移群集.这里,就我的理解,和大家简单探讨下,有不足或错误之处还请各位指出! 这些 ...

  6. 字符串匹配算法Java_如何简单理解字符串匹配算法?

    这篇文章来说说如何简单理解KMP,BM算法.之前看过一些文章说,KMP算法很难理解. 可我并不觉得. 我反而觉得它容易理解.平时我们写java代码的时候, 判断一个字符串是否存在包含另一个字符串都是直 ...

  7. python yield的简单理解

    2019独角兽企业重金招聘Python工程师标准>>> yield是个生成器,它可以使一个方法变成可迭代的方法,每次迭代返回yield后面的值 简单理解: >>>d ...

  8. linun——SElinux的简单理解

    SElinux简单理解 一.什么是SElinux? SELinux 全称 Security Enhanced Linux (安全强化 Linux),是 MAC (Mandatory Access Co ...

  9. git pull 是到工作区还是暂存区_每天一Git之简单理解工作区和暂存区

    每天一Git之简单理解工作区和暂存区 1. 工作区与暂存区命令初体验 1.1. 暂存区文件与文件夹管理 [root@number ~]# cd GitDir/git_learning/ [root@n ...

最新文章

  1. 面试官:听说你sql写的挺溜的,你说一说查询sql的执行过程
  2. 正则表达式在线自动生成器
  3. 水晶报表错误:bobj is not defined
  4. hadoop--常见错误及解决方法
  5. golang利用json.Unmarshal转json为map、slice类型
  6. SQLServer通过链接服务器调用Oracle 存储过程
  7. Linux下安装配置git
  8. mysql中为啥只显示一条语句_MySQL 笔记整理(19) --为什么我只查一行的语句,也执行这么慢?...
  9. 微信小程序图标 icon组件
  10. 在线常用正则表达式可视化生成与测试工具与示例 Regular Expression
  11. ad20如何画出pcb板大小_如何用AD更改PCB板子尺寸
  12. 孙子算经-秦王暗点兵问题
  13. 95%的人都会答错的类加载的问题
  14. AHRS姿态解算说明(加速度+陀螺仪+磁力计原理及原始数据分析)
  15. 概念模型,逻辑模型,物理模型
  16. php高性能框架phaicon,3分钟快速入门php高性能框架Phalcon
  17. IllegalArgumentException 异常
  18. 《科技创业启示录》一第2章 克里斯·巴顿、菲利普·安格布瑞希、迪拉伊·慕克吉、艾弗里·王 科技创业启示录...
  19. ValueError: List argument ‘indices‘ to ‘Sparse Concat‘ Op with length 0 shorter than minimum length2
  20. 【Windows + Linux】专业级:安装操作系统 + 多系统 + GhostCast Server PXE 网刻基础坑精通详解

热门文章

  1. 二叉树的深度优先遍历与广度优先遍历 [ C++ 实现 ]
  2. 配置JDK时环境变量path和JAVA_HOME的作用
  3. Miner3D Enterprise 企业版
  4. 百度2011招聘笔试题+答案解析
  5. UEFI主板GPT方式安装CentOS 6.4
  6. [ 云炬创业基础笔记]商业模式创新
  7. USTC English Club Note20171015(5)
  8. [:zh]<机械课程设计>五种表格自动填写部分[:]2017-12-23
  9. GitHub如何下载单个文件夹
  10. 如何显示服务器上的图片,显示服务器上的图片怎么写