代码随想录算法训练营第三十八天 _ 动态规划_509.斐波那契数、70.爬楼梯、746. 使用最小花费爬楼梯。

学习目标:

动态规划五部曲:
① 确定dp[i]的含义
② 求递推公式
③ dp数组如何初始化
④ 确定遍历顺序
⑤ 打印递归数组 ---- 调试
引用自代码随想录!

60天训练营打卡计划!

学习内容:

509.斐波那契数

  • 动态规划五步曲:
    ① 确定dp[i]的含义 : 第i个斐波那契数的值
    ② 求递推公式 : dp[i] = dp[i-1] +dp[i-2]
    ③ dp数组如何初始化 : dp[0] = 1 dp[1] = 1
    ④ 确定遍历顺序 : 从前向后
// 动态规划
class Solution {
    public int fib(int n) {
        int[] dp = new int[n + 1];
        dp[0] = 0;
        if(n == 0)  return dp[0];
        dp[1] = 1;
        if(n == 1)  return dp[1];
        for(int i = 2; i <= n; i++){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
}

// 递归实现
class Solution {
    // 该递归的传入参数应该是 F(n - 1) 和 F(n - 2) 和循环次数,返回值应该是 F(n)
    private int traversal(int pre, int cur, int num){
        // 递归结束条件
        if(num == 0) return pre + cur;
        // 最小递归的逻辑
        int sum  = traversal(cur, pre+cur, num-1);
        // 这里的return是为了在最深的递归结束之后,其他较浅的递归逐层向上返回结果。
        return sum;
    }

    public int fib(int n) {
        int pre = 0;
        if(n == 0)  return pre;
        int cur = 1;
        if(n == 1)   return cur;
        return traversal(pre, cur, n-2);
    }
}

70.爬楼梯

  • 动态规划五步曲:
    ① 确定dp[i]的含义 : 到第i级台阶有dp[i]种方法
    ② 求递推公式 : dp[i] = dp[i-1] +dp[i-2]
    ③ dp数组如何初始化 : dp[1] = 1 dp[2] = 2
    ④ 确定遍历顺序 : 从前向后
  • 这个规律只是恰好可以和递推关系对应起来,但是很难说明真实的数量间的关系。
class Solution {
    public int climbStairs(int n) {
        int[] dp = new int[n+1];
        dp[1] = 1;
        if(n == 1)  return dp[1];
        dp[2] = 2;
        if(n == 2)  return dp[2];
        for(int i = 3; i <= n; i++){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
}

class Solution {
    private int traversal(int pre, int cur, int num){
        int next = pre + cur;
        if(num == 0)     return next;

        return traversal(cur, next, num - 1);
    }

    public int climbStairs(int n) {
        int pre = 1;
        if(n == 1)   return pre;
        int cur = 2;
        if(n == 2)   return cur;
        return traversal(pre, cur, n - 3);
    }
}


746. 使用最小花费爬楼梯

  • 动态规划五步曲:
    ① 确定dp[i]的含义 : 到第i级台阶的最小体力消耗
    ② 求递推公式 : dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]) ,其中cost[i-1]是在第i-1阶台阶时的体力消耗。
    ③ dp数组如何初始化 : dp[0] = 0 dp[1] = 0 cost[0] = 10 cost[1] = 15
    ④ 确定遍历顺序 : 从前向后

  • 在实现的过程中还有一些其他的细节,比如说最大阶要比cost的长度大1.

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int size = cost.length;
        // 台阶的最大高度一定比开销大1
        int[] dp = new int[size+1];
        dp[0] = 0;
        dp[1] = 0;
        if(size == 0 || size == 1)    return 0;

        for(int i = 1; i < size; i++){
            // 因为递推公式是卡着目标线写出来的,故一定可以达到最高的台阶
            dp[i+1] = Math.min(dp[i-1] + cost[i-1], dp[i] + cost[i]);
        }
        // 这里返回的是最高级的台阶
        return dp[size];
    }
}

学习时间:

  • 上午两个半小时,整理文档半小时。

你可能感兴趣的:(刷题训练心得,算法,动态规划)