4步套路,解决动态规划问题

1、确定问题状态

  • 提炼最后一步
  • 的问题转化

2、转移方程,把问题方程化
3、按照实际逻辑设置初始条件和边界情况
4、确定计算顺序并求解

结合实例感受下:

你有三种硬币,分别面值2元,5元和7元,每种硬币都有足够多。买一本书需要27元。如何用最少的硬币组合正好付清,不需要对方找钱?

关键词“用最小的硬币组合正好付清”——“最小的组合”,求最值问题,动态规划

**正常人第一反应思路:**最少硬币组合?优先使用大面值硬币——7+7+7+5=26 额?可求解目标是27啊……改算法——7+7+7+2+2+2=27,总共用了6枚硬币正好27元.实际正确答案:7+5+5+5+5=27,才用了5枚硬币。所以这里贪心算法是不正确的。

套路用起来:

第一步,确定问题状态。

动态规划问题求解需要先开一个数组,并确定数组的每个元素f[i]代表什么,就是确定这个问题的状态。类似于解数学题中,设定X,Y,Z代表什么。

A、确定状态首先提取【最后一步】

最优策略必定是K枚硬币a1, a2,…, aK 面值加起来是27。

找出不影响最优策略的最后一个独立角色,这道问题中,那枚最后的硬币“aK”就是最后一步。把aK提取出来,硬币aK之前的所有硬币面值加总是27- aK因为总体求最硬币数量最小策略,所以拼出27- aK 的硬币数也一定最少(重要设定)。

B、**转化子问题。**最后一步aK提出来之后,我们只要求出“最少用多少枚硬币可以拼出27- aK”就可以了。

这种与原问题内核一致,但是规模变小的问题,叫做子问题。

为简化定义,我们设状态f(X)=最少用多少枚硬币拼出总面值X。我们目前还不知道最后的硬币aK面额多少,但它的面额一定只可能是2/5/7之一。如果aK是2,f(27)应该是f(27-2) + 1 (加上最后这一枚面值2的硬币)如果aK是5,f(27)应该是f(27-5) + 1 (加上最后这一枚面值5的硬币)如果aK是7,f(27)应该是f(27-7) + 1 (加上最后这一枚面值7的硬币)除此以外,没有其他的可能了。

至此,通过找到原问题最后一步,并将其转化为子问题。为求面值总额27的最小的硬币组合数的状态就形成了,用以下函数表示:

f(27) = min{f(27-2)+1, f(27-5)+1, f(27-7)+1}

第二步,转移方程,把问题方程化。

f[X] = min{f[X-2]+1, f[X-5]+1, f[X-7]+1}(动态规划都是要开数组,所以这里改用方括号表示)

实际面试中求解动态规划类问题,正确列出转移方程正确基本上就解决一半了。

但是请问:这与递归有什么不同??

递归的解法:

// f(X)返回最少用多少枚硬币拼出Xint f(int X) {// 0元钱只要0枚硬币if (X == 0) return 0;// 初始化用无穷大(为什么是正无穷?)int res = MAX_VALUE;// 最后一枚硬币是2元if (X >= 2) {res = Math.min(f(X – 2) + 1, res);}// 最后一枚硬币是5元if (X >= 5) {res = Math.min(f(X – 5) + 1, res);}// 最后一枚硬币是7元if (X >= 7) {res = Math.min(f(X – 7) + 1, res);}return res;}

执行图如下:

要算f(27),就要递归f(25)、f(22)、f(20),然后下边依次递归……(三角形表示)。

问题明显——重复递归太多。

这是求f(27),还可以勉强递归。如果求f(100)呢?简直是天文数字。最终结果就是递归超市。

求总体最值,一定优先考虑动态规划不要憨憨的去递归。

插入一下~

需要掌握的动态规划面试解题技巧还包括坐标型、位操型、序列型、博弈型、背包型、双序列以及一些高难面试题解。

本文篇幅有限无法逐一讲清,大家来白嫖我的在线分享吧(纯干货)。

第三步,按照实际逻辑设置边界情况和初始条件。

**【必做】**否则即使转移方程正确也大概率无法跑通代码。

f[X] = min{f[X-2]+1, f[X-5]+1, f[X-7]+1}的边界情况是[x-2]/[x-5]/[x-7]不能小于0(硬币面值为正),也不能高于27。

故对边界情况设定如下:

如果硬币面值不能组合出Y,就定义f[Y]=正无穷例如f[-1]=f[-2]=…=正无穷;f[1] =min{f[-1]+1, f[-4]+1,f[-6]+1}=正无穷,

**特殊情况:**本题的F[0]对应的情况为F[-2]、F[-5]、F[-7],按照上文的边界情况设定结果是正无穷。

但是实际上F[0]的结果是存在的(即使用0个硬币的情况下),F[0]=0。可是按照我们刚刚的设定,F[0]=F[0-2]+1= F[-2]+1=正无穷。

岂不是矛盾?

这种用转移方程无法计算,但是又实际存在的情况,就必须通过手动定义。

这里手动强制定义初始条件为:F[0]=0.

而从0之后的数值是没矛盾的,比如F[1]= F[1-2]+1= F[-1]+1=正无穷(正无穷加任何数结果还是正无穷);F[2]= F[2-2]+1= F[0]+1=1……

第四步,确定计算顺序并计算求解

那么开始计算时,是从F[1]、F[2]开始呢?还是从F[27]、F[26]开始呢?

判断计算顺序正确与否的原则是:当我们要计算F[X](等式左边,如F[10])的时候,等式右边(f[X-2], f[X-5], f[X-7]等)都是已经得到结果的状态,这个计算顺序就是OK的。

实际就是从小到大的计算方式(偶有例外的情况我们后边再讲)。

例如我们算到F[12]的时候,发现F[11]、F[10]、F[9]都已经算过了,这种算法就是对的;而开始算F[27]的时候,发现F[26]还没有算,这样的顺序就是错的。

很显然这样的情况下写一个FOR循环就够了。

回到这道题,采用动态规划的算法,每一步只尝试三种硬币,一共进行了27步。算法时间复杂度(即需要进行的步数)为27*3。

与递归相比,没有任何重复计算。

**原题练习及实际代码:**这道题是lintcode编号669的Coin Change问题。代码如下:

public int coinChange(int[] A, int M){// A = [2,5,7]// M = 27int[] f = new int[M + 1];int n = A.length; // 硬币的种类// 初始化, 0个硬币f[0] = 0;// f[1], f[2], ... , f[27] = Integer.MAX_VALUEfor (int i = 1; i <= M; i++){f[i] = Integer.MAX_VALUE;}for (int i = 1; i <= M; i++){// 使用第j个硬币 A[j]// f[i] = min{f[i-A[0]]+1, ... , f[i-A[n-1]]+1}for (int j = 0; j < n; ++j){// 如果通过放这个硬币能够达到重量iif (i >= A[j] && f[i - A[j]] != Integer.MAX_VALUE) {// 获得i的重量的硬币数就可能是获得i-A[j]重量硬币数的方案+1// 拿这个方案数量与原本的方案数打擂台,取最小值就行f[i] = Math.min(f[i - A[j]] + 1, f[i]);}}}if (f[M] == Integer.MAX_VALUE){return -1;}return f[M];}

最后总结:

1、这是求最值问题,用动态规划方式求解。2、进入求解过程,先确定问题状态

  • 提炼最后一步
    (最优策略中使用的最后一枚硬币aK)
    -子问题转化 (最少的硬币拼出更小的面值27-aK)
    3、构建转移方程 f[X] = min{f[X-2]+1, f[X-5]+1, f[X-7]+1}
    (求min是因为题目要求求最小)
    4、设置初始条件和边界情况 f[0] = 0, 如果不能拼出Y,f[Y]=正无穷
    5、确定计算顺序并计算求解
    f[0], f[1], f[2]……

实际上按照以上4步套路,基本上可以应对绝对大多数的动态规划面试题。

Docker步步实践

目录文档:

①Docker简介

②基本概念

③安装Docker

④使用镜像:

⑤操作容器:

⑥访问仓库:

⑦数据管理:

⑧使用网络:

⑨高级网络配置:

⑩安全:

⑪底层实现:

⑫其他项目:

k-1627352685734)]

⑩安全:

[外链图片转存中…(img-v1sUm7Uc-1627352685735)]

⑪底层实现:

[外链图片转存中…(img-pZiEWGkw-1627352685736)]

⑫其他项目:

[外链图片转存中…(img-i7jy1hl9-1627352685737)]

有需要完整版源码+笔记的朋友点击这里免费获取

Javasocket聊天程序,进阶学习资料!相关推荐

  1. ssm基于微信小程序的学习资料销售平台+ssm+uinapp+Mysql+计算机毕业设计

    本微信小程序的学习资料销售平台以ssm作为框架,b/s模式以及MySql作为后台运行的数据库,同时使用Tomcat用为系统的服务器.本系统主要包括以下功能模块:首页.个人中心.用户管理.资料类型管理. ...

  2. 优秀游戏程序员学习资料推荐

    这两天给单位的技术做的一次学习材料推荐培训,直接ppt上拷过来的.          优秀游戏程序员学习资料推荐 主讲人:臧旭 前言 今天提到的纯粹是我个人心得和理解,可能片面,也可能以偏概全. 目的 ...

  3. 人工智能、机器学习、深度学习从入门到进阶学习资料整理

    最近整理了下在这里分享给大家,欢迎大家点赞收藏. 学习社区 神力AI(MANA):国内最大的AI代码平台. Learn AI:一个AI学习交流中心. AI研习社:一个专注于AI开发者和学术青年求知求职 ...

  4. 安卓开发陀螺仪!首发10万字Android开发实战文档,进阶学习资料!

    Gradle是什么? Gradle是一种构建语言,目前是Android的默认构建工具,我们编写的编译脚本,其实就是玩Gradle的API,所以从它更底层的意义上看,是一个编程框架. 因为涉及的内容很多 ...

  5. 太赞了!没想到一个Handler还有中高级几种问法,进阶学习资料!

    缘起 经过近十年的发展,Android技术优化日新月异,如今Android 10.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS.到了各大厂商手里,改源码.自定义系统, ...

  6. Java程序员学习资料分享,等你来收藏!

    你有没有,想入门 Java.Python.Go.大数据.区块链等编程技术,而却无从入手? 你有没有,为了提升自己,去花费很长时间,苦苦寻觅学习资源,而最终却寻而无获? 最近,时不时的又有新老朋友,索要 ...

  7. 实现原理讲解!2020Android目前最稳定和高效的UI适配方案!进阶学习资料!

    前言 组件化是 保持整个 App 可持续地进行高质量开发的基础,近年来也是业界一直在积极探索和实践的方向,在深入理解组件化架构的过程中,将不断考验你的技术深度与广度: 实践中我还参考了十几家技术团队的 ...

  8. 2021Java进阶学习资料!java自学宝典pdf下载

    一.一面 1小时40几分钟,基本会的被问完了 1.介绍项目,考虑没考虑过服务器挂了怎么办 这里应该是考查系统架构 2.面向对象特性 3.怎么理解多态 4.接口和抽象类的区别 5.说说并发是怎么回事,有 ...

  9. Java进阶学习资料,java小程序开发面试题

    引言 技术好就一定能写出优质的代码吗?不能,对于做开发的人来说,学到的技术知识是理论性的,只有把知识代入到真实的实战案例中才能快速将理论转变为技能. 一直在网上看到过很多关于类似的资料,要么就是版本比 ...

最新文章

  1. 构建伪Update服务器工具isr-evilgrade
  2. GitHub回应突然断供:身在美国不由己,无权提前通知预警
  3. 【Android 进程保活】Android 进程优先级 ( 前台进程 | 可见进程 | 服务进程 | 后台进程 | 空进程 )
  4. 如何编写oracle存储过程
  5. BFE Ingress Controller正式发布!
  6. q7goodies事例_Java 8 Friday Goodies:本地交易范围
  7. Flutter-现有iOS工程引入Flutter
  8. 无法读取源文件或磁盘_raid磁盘阵列作用
  9. python 时分秒毫秒_第一篇:Python处理时间日期
  10. 三星内存编码_内存条上面的编码的含义
  11. 手机阅读成全球3G赢利点:一年1亿美元市场
  12. PDF阅读器哪个好用?看完这篇文章就可以不用再问了
  13. 某CRM旗舰版功能齐全客户管理系统源码
  14. 我的华为云售后日常(一)
  15. GB50052-2009供配电系统设计规范1
  16. PR曲线与ROC曲线
  17. 爬虫基础 || 2.1 request介绍(功能比urllib丰富,附上简单的知乎爬虫)
  18. php对接微信调用不到头像,【微信公众号小程序】微擎获取用户头像失败的问题如何处理— 亲测 可用 持续更新...
  19. idea中svn颜色代表的文件状态
  20. Python 基于modbus tcp 协议 实现与plc通信

热门文章

  1. 大疆Livox_mid 40雷达初体验
  2. 比害时新己50米地面蹦极交吻(组图)
  3. Apache web服务的学习与应用
  4. 推荐几个微信小程序毕业设计的课题
  5. 用英语简述计算机的启动过程,计算机的启动过程(详细)
  6. 上下文无关文法的作用
  7. 中国科学院大学计算机调剂,【中国科学院大学考研调剂官网】中国科学院大学研究生院:2016年调剂信息...
  8. matlab怎么画结构振型,matlab子空间迭代法求结构频率和振型
  9. python中源程序执行的方式是什么_python源程序执行的方式有什么
  10. 英语外企生活常用口语