- 动态规划基础-代码随想录 (programmercarl.com)
-
509斐波那契数
- 代码随想录 (programmercarl.com)
-
讲解观后感
- 非常经典的算法题。解题代码不是很难。重要的是利用这道题体会动态规划的方法。
- 动规五部曲:
这里我们要用一个一维dp数组来保存递归的结果
-
- 确定dp数组以及下标的含义
dp[i]的定义为:第i个数的斐波那契数值是dp[i]
-
- 状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];
-
dp[0]=0 dp[1]=1
-
- 确定遍历顺序
从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后遍历的
-
- 举例推导dp数组
按照这个递推公式dp[i] = dp[i - 1] + dp[i - 2],我们来推导一下,当N为10的时候,dp数组应该是如下的数列:0 1 1 2 3 5 8 13 21 34 55
-
解题代码
- 递归
-
func fib(n int) int {
if n == 0 {
return 0
}
if n == 1 {
return 1
}
return fib(n-1)+fib(n-2)
}
- 迭代
-
func fib(n int) int {
if n < 2 {
return n
}
a, b, c := 0, 1, 0
for i := 1; i < n; i++ {
c = a + b
a, b = b, c
}
return c
}
-
70爬楼梯
- 代码随想录 (programmercarl.com)
-
第一印象
- 可以想象,到达n级台阶的方法一定是由n-1或n-2上来。那么爬到n的方法数量就是爬到n-1的方法数量和n-2的方法数量之和。这时我们发现这就是熟悉的斐波那契。
-
解题代码
-
func climbStairs(n int) int {
if n == 1 {
return 1
}
dp := make([]int, n+1)
dp[1] = 1
dp[2] = 2
for i := 3
dp[i] = dp[i-1] + dp[i-2]
}
return dp[n]
/*
dp := make([]int, n)
dp[0] = 1
dp[1] = 2
for i := 2
dp[i] = dp[i-1] + dp[i-2]
}
return dp[n-1]
*/
}
-
使用最小花费爬楼梯
- 代码随想录 (programmercarl.com)
-
第一印象
- 还是按照动态规划的方法:
- 确定dp数组及其下标的含义、确定递推共识、确定初始化、确定遍历顺序、举例推导递推公式
-
解题代码
-
func minCostClimbingStairs(cost []int) int {
len := len(cost)
dp := make([]int, len)
dp[0] = 0
dp[1] = 0
for i:=2;i<len;i++ {
dp[i] = min(dp[i-2]+cost[i-2], dp[i-1]+cost[i-1])
}
return min(dp[len-1]+cost[len-1], dp[len-2]+cost[len-2])
}
func min(x int, y int) int {
if x > y {
return y
} else {
return x
}
}