Day32 | Part1
约 442 个字 34 行代码 预计阅读时间 2 分钟
动态规划介绍
动规(Dynamic Programming即DP), 若某一问题有很多重叠子问题,使用DP是最有效的
DP中 每一个状态一定是由上一个状态推导出来的 (区分于贪心)
贪心没有状态推导,而是从局部直接选最优的
解题步骤
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历的顺序
- 举例推导dp数组
若出问题: 最好方式就是把dp数组打印出来,看看是不是按照自己思路推导的!
- 写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍
509.斐波那契数
当然可以直接用递归:
1 2 3 4 |
|
动规:
dp[i]
的定义为:第i
个数的斐波那契数值是dp[i]
dp[i] = dp[i - 1] + dp[i - 2]
(递推公式给出)- 初始化:
dp[0] = 0, dp[1] = 1;
- 遍历顺序: 从前到后
- 具体推导:
0 1 1 2 3 5 8 13 21 34 55...
1 2 3 4 5 6 7 |
|
但其实不需要维护整个vector
, 仅仅维护两个值即可
1 2 3 4 5 6 7 8 9 |
|
70.爬楼梯
- dp[i]: 爬到第i层楼梯,有dp[i]种方法
dp[i] = dp[i - 1] + dp[i - 2]
- 初始化:
dp[1] = 1, dp[2] = 2;
n > 0, 不考虑n = 0的情况 - 从前到后进行遍历
- 举例若n = 5 :
1 2 3 5 8...
不就是fibonacci(如图)
1 2 3 4 5 6 7 |
|
746.使用最小花费爬楼梯
- dp[i]到达第i个台阶花费的体力dp[i]
- 两个途径得到dp[i], 从dp[i - 1] 或dp[i - 2]分别加上cost, 选两者小的
dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
- 初始化:
dp[0] = 0, dp[1] = 0;
- 遍历顺序: 从前到后
- 举例: 参考图
1 2 3 4 5 6 7 |
|