动态规划类题目综述

动态规划题目特点:

1,计数

—机器人有多少种方式走到右下角

—有多少种方法选出k个数使得和是sum

2,求最大最小值

—从左上角走到右下角路径的最大数字和

—最长上升子序列问题

3,求存在性

—取石子游戏,先手是否必胜

—能不能选出k个数使得和是sum

 

最值型动态规划例题

例题:有2,5,7三种面值的硬币,如何以最少的硬币拼成27(LeetCode上第322题!)

  • 动态规划组成部分之一:确定状态

       确定状态需要有两个意识,最优策略的最后一步和子问题。在本例题中可以理解为拼成27的最后一枚硬币是Ak,故最优解法是k-1枚硬币拼成了27-Ak,这样的思考方式就兼顾了最后一步和子问题,也就确定了状态。状态f(X) = 由最少用多少枚硬币拼出X,其中f(X)是数组!

子问题:f(X) = f(X-2) +1

             f(X) = f(X-5) +1

             f(X) = f(X-7) +1 ,求以上三个式子的min

       题目分析到这里,其实可以用递归的思想进行求解,但递归解法涉及的时间复杂度太大(许多情况需要重复计算),所以接着往下分析。

  • 动态规划组成部分之二:转移方程,根据子问题定义直接得到

对于任意X,f[X] = min{f(X-2) +1,f(X) = f(X-5) +1,f(X) = f(X-7) +1},这里再次强调,f[X]是数组!

  • 动态规划组成部分之三:初始条件与边界情况,细心、考虑周全

      在往下分析的过程中会遇到两个要考虑的地方,当X-2,X-5,X-7小于0怎么办以及什么时候停下来?我们可以事先定义当拼不出X时,f[X] = 正无穷,这是边界情况,初始条件f[0] = 0

  • 动态规划组成部分之四:计算顺序,利用之前的计算结果

      一般情况下是按照从小到大的顺序计算,先计算初始条件f[0],再计算f[1],f[2],.....,当我们计算到f[X]时,f(X-2),f(X-5), f(X-7)都已经计算过了,至此问题得解。

 

代码:

     

 

计数型动态规划例题

例题:Unique Path,机器人从左上角走到右下角多少种走法(LeetCode上第62题!)

  • 确定状态:f[i][j]为机器人有多少种方法走到(i,j)

  • 转移方程:f[i][j] = f[i - 1][j] + f[i][j - 1]

  • 初始条件:f[0][0] = 1,机器人只有一种方式走到左上角(注意不能是0)

  • 边界情况:i = 0或j = 0,此时只能有一种方法走过来,f[i][j] = 1,这步很重要!

  • 计算顺序:对于二维问题,先一行行的计算,再计算列(从左到右),最后返回值为f[i][j]

  • 代码如下:

 

                        

 

存在性动态规划例题

例题:Jump Game (最好的解法是贪心算法)

  • 确定状态:设f[j]表示青蛙能不能跳到石头j

  • 转移方程:f[j] = OR 0<=i<j) (f[i] AND i + a[i] >= j)

  • 初始条件:f[0] = true

  • 边界情况:无

  • 计算顺序:计算f[0],f[1],f[2],...,答案是f[n-1],第一块石头是f[0]

  • 代码如下:

 

            

 

  • Jump Game2,求出最少要跳几次才能到达最后一块石头,代码如下:

 

        

下面是一种高效的解法:

 

                    

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值