随想录Day38 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯 | 动态规划

121 阅读2分钟

509. 斐波那契数

题目链接:509. 斐波那契数

思路: 动规五部曲 

1.确定dp数组以及下标的含义

dp[i]的定义为:第i个数的斐波那契数值是dp[i]

2.确定递推公式

状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];

3.dp数组如何初始化

dp[0] = 0; dp[1] = 1;

4.确定遍历顺序

从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后遍历的

5.举例推导dp数组

按照这个递推公式dp[i] = dp[i - 1] + dp[i - 2],我们来推导一下,当N为10的时候,dp数组应该是如下的数列: 0 1 1 2 3 5 8 13 21 34 55 如果代码写出来,发现结果不对,就把dp数组打印出来看看和我们推导的数列是不是一致的。

class Solution {
    public int fib(int n) {
        int[] memo = new int[n + 1];
        return help(n, memo);
    }

    int help(int n, int[] memo) {
        if (n == 1 || n == 0) return n;
        if (memo[n] != 0) return memo[n];
        memo[n] = help(n - 1, memo) + help(n - 2, memo);
        return memo[n];
    }
}

70. 爬楼梯

题目链接:70. 爬楼梯

思路: 这道题目和斐波那契数很像,因为状态转移方程都是dp[n] = dp[n - 1] + dp[n - 2]

class Solution {
    public int climbStairs(int n) {
        if (n <= 2) return n;
        int a = 1, b = 2;
        int sum = 0;
        for (int i = 3; i <= n; i++) {
            sum = a + b;
            a = b;
            b = sum;
        }
        return sum;
    }
}

746. 使用最小花费爬楼梯

题目链接:746. 使用最小花费爬楼梯

思路: 动规五部曲 

1.确定dp数组以及下标的含义

dp[i]的定义为:到第i层所需要的花费[i]

2.确定递推公式

状态转移方程 dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);

3.dp数组如何初始化

dp[0] = 0; dp[1] = 0;

4.确定遍历顺序

从前向后遍历

5.举例推导dp数组

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        // dp数组定义 dp[i]:到达第i层的最低花费
        int len = cost.length;
        int[] dp = new int[len + 1];
        dp[0] = 0;
        dp[1] = 0;
        for (int i = 2; i < dp.length; i++) {
            dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[len];
    }
}