以lc746为例
746. 使用最小花费爬楼梯
数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值
cost[i](下标从 0 开始)。每当你爬上一个阶梯你都要花费对应的体力值,
一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。
请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1
的元素作为初始阶梯。
//什么是子问题?
//子问题是和原问题相似,但规模较小的问题
//子问题需要具备哪些性质?
// 原问题要能由子问题表示
// 一个子问题的解要能通过其他子问题的解求出
//动态规划实际上就是通过求这一堆子问题的解,来求出原问题的解
//原问题:到楼层顶部的最低花费
//子问题:到楼层i的最低花费(i = 0,1,2……1000)
//确定dp数组以及下标的含义:dp[i]表示到达第i层的最低花费为dp[i]
//确定递推关系:dp[i] = min(dp[i - 1] + nums[i - 1], dp[i - 2] + nums[i - 2])
//dp数组初始化 dp[0] = dp[1] = 0
//确定dp数组的计算顺序 dp[i] 依赖于 dp[i - 1] 和 dp[i - 2]
补充
lc上对动态规划笼统的概述
动态规划常常适用于有重叠子问题和最优子结构性质的问题,并且记录所有子问题的结果,因此动态规划方法所耗时间往往远少于朴素解法。
使用动态规划解决的问题有个明显的特点,一旦一个子问题的求解得到结果,以后的计算过程就不会修改它,这样的特点叫做无后效性,求解问题的过程形成了一张有向无环图。动态规划只解决每个子问题一次,具有天然剪枝的功能,从而减少计算量。
总结
动态规划解决什么样的问题?
- 如果一个原问题,可以通过求解与原问题相似,但是规模较小的子问题来求解。同时子问题的解同样可以通过
比子问题规模更小的子问题求解。那么这样的问题,可以通过动态规划来求解。
动态规划中子问题的有哪些性质
- 原问题可以通过字问题求解
- 子问题可以通过规模更小的子问题求解
- 一旦某一子问题被求解得到,那么该子问题的结果就不会被改变(为什么?? 待解决)