告别动态规划,清华学霸提灯给你讲解DP,听不懂你打我
Posted 九章算法
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了告别动态规划,清华学霸提灯给你讲解DP,听不懂你打我相关的知识,希望对你有一定的参考价值。
最近九章算法和阿里云合办了一场在线编程大赛,根据赛后数据显示,超过
70%
的选手认为动态规划是最难对付的题型。
而自从动态规划出现在算法面试后,同样成为求职者绕不开的“噩梦”。
除了Google,TikTok等常面DP的大厂外,
现在就连
亚麻电面阶段也考DP
了,如果没有准备的话,分分钟就可能挂面。
动态规划的一大难点就是题型众多而又没有统一的解法。想要熟练掌握往往
需要大量刷题来练习
,这么做对于本就不充裕的准备时间来说,性价比太低。
作为清华学霸,全国算法竞赛金牌,ACM全球总决赛选手,FLAG资深面试官,
侯卫东
老师凭借丰富的刷题和面试经验,总结了一套针对动态规划的“
4步解题法
”。
今天通过一道经典题,侯老师给大家讲讲如何用4步解题法搞定动态规划题型。
你有三种硬币,分别面值2元,5元和7元,每种硬币都有足够多。买一本书需要27元。如何用最少的硬币组合正好付清,不需要对方找钱?
从左上角到右上角路径的最大数字和、最长上升子序列长度
如果你碰到一个问题是以上提问方式,那么有90%的概率是使用动态规划来求解。要重点说明的是,若问题是让你求出“所有的”方案和结果,则肯定不是使用动态规划。
再回到这道题,“最少的硬币组合”,求最值问题,可以用DP来解。
状态在动态规划中的作用属于定海神针。解动态规划时需要开一个数组,这里的“状态”就是指数组的每个元素f[i]或f[i][j]代表什么。
这道题中,我们不知道最优策略是什么,但最优策略肯定是K枚硬币a1,a2……aK面值加起来是27。
① 我们不关心前面的K-1枚硬币是怎么拼出27-aK的,也不知道aK和K,但是可以确定前面的硬币拼出了27-aK。
② 因为是最优策略,所以拼出的27-ak硬币数一定要最少(否则就不是最优策略)
现在问题变成了:最少用多少枚硬币可以拼出27-aK。也就是将原问题(27)转化成了一个子问题,而且规模更小(27-aK)。
这种与原问题内核一致,但是规模更小的问题,就叫子问题。
为了简化定义,我们设状态f(X)=最少用多少枚硬币拼出X。所以问题就从求f(X)变成求f(X-aK)
我们目前还不知道最后的硬币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的硬币)
因为要求最少的硬币数,所以问题的解就可以这样表示:
f(27) = min{f(27-2)+1, f(27-5)+1, f(27-7)+1}
对于任意X,f[X] = min{f[X-2]+1, f[X-5]+1, f[X-7]+1}
实际面试中,如果正确列出转移方程,问题基本就解决一半了。
很多同学基本也可以做到写出状态转移方程,但真正写程序的时候往往会出现很多错误或问题。
这就涉及到在在代码前的两个重要步骤,就是我们4步解题法的第三步和第四步。
f[X] = min{f[X-2]+1, f[X-5]+1, f[X-7]+1}的边界情况是X-2, X-5或者X-7不能小于0(硬币面值为正)
f[1] =min{f[-1]+1, f[-4]+1,f[-6]+1}=正无穷,表示拼不出1
特殊情况:本题的F[0]对应的情况为F[-2]、F[-5]、F[-7],按照上文的边界情况设定结果是正无穷。
但是实际上F[0]的结果是存在的(即使用0个硬币的情况下),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]还没有算,这样的顺序就是错的。
回到这道题,采用动态规划的算法,每一步只尝试三种硬币,一共进行了27步。算法时间复杂度(即需要进行的步数)为27*3。
原题练习:
LintCode 669.Coin Change
按照以上4步套路,基本上可以解决绝大多数类型的动态规划题。
除了最值型动态规划,想要了解4步法在更多类型动态规划中的运用,可以来听侯卫东老师的《
动态规划专题班
》。
在《动态规划专题》试听课中,侯卫东老师毫无保留地详细讲解了4步法具体如何应用。还没搞懂动态规划的同学一定要来听听看哇!
侯卫东 ACM世界总决赛选手
清华大学毕业,全国算法竞赛金牌得主,参加过ACM国际大学生程序设计竞赛全球总决赛。斩获
Google,Facebook,Microsoft,Uber, Dropbox
等多家offer,拥有丰富的面试和面试官经验。
什么是动态规划
动态规划和递归的区别
动态规划的解题要领
动态规划三大类
求最值/计数/可行性
常见动态规划类型总结
以上是关于告别动态规划,清华学霸提灯给你讲解DP,听不懂你打我的主要内容,如果未能解决你的问题,请参考以下文章
小姐姐提灯给你讲讲动态规划(万字长文)
这次让你彻底学会redis中跳表原理,不懂你打我
清华学霸的解题秘籍,拿下动态规划就4步!
清华学霸总结的动态规划4步曲,仅这篇动归够了
动态规划&&状压
大端模式小端模式详解(不懂你打我,略略~~)