算法day28-动态规划(1)

目录

  1. 斐波那契数
  2. 爬楼梯
  3. 使用最小花费爬楼梯

 一、斐波那契数

https://leetcode.cn/problems/fibonacci-number/?envType=problem-list-v2&envId=8At1GmaZ

   这道斐波那契数列问题是动态规划的经典入门案例。我们通过定义 dp[i] 表示第 i 个斐波那契数,利用状态转移方程 dp[i] = dp[i - 1] + dp[i - 2] 从前向后推导,并以 dp[0]=0, dp[1]=1 为初始状态,最终得到 dp[n] 作为答案。该方法有效避免了递归的重复计算,时间复杂度为 O(n),是理解动态规划“状态定义 + 递推关系 + 初始条件”三要素的绝佳练习。

class Solution {
    public int fib(int n) {
        //1.确定dp数组的含义:dp[i]表示第i个斐波那契数值
        //2,确定递推公式:dp[i] = dp[i-1] + dp[i-2];
        //3.初始化
        if(n==0 || n==1){
            return n;
        }
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 1;
        //4.确定遍历顺序:由前面推出后面
        for(int i=2; i<=n; i++){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
        //5.打印dp数组
    }
}

 

二、爬楼梯

https://leetcode.cn/problems/climbing-stairs/?envType=problem-list-v2&envId=8At1GmaZ

   这道题是经典的爬楼梯问题,实质是一个斐波那契型动态规划问题。我们定义状态 dp[i] 表示爬到第 i 层楼梯的方法数。由于每次只能爬 1 或 2 层,所以到达第 i 层的方法可以由第 i-1 层爬 1 层上来,或由第 i-2 层爬 2 层上来,因此状态转移方程为:dp[i] = dp[i - 1] + dp[i - 2]。初始状态为 dp[1] = 1dp[2] = 2,表示只有一层时只有一种爬法,两层时可以一次爬两层或分两次。最终返回 dp[n] 即为答案。该题时间复杂度为 O(n),是理解 DP 状态转移思想的经典练习。

class Solution {
    public int climbStairs(int n) {
        //1.确定dp数组的含义:dp[i],达到第i层有多少种方法
        //2.确定递推公式:dp[i] = dp[i-1]+dp[i-2];
        //3.初始化
        if(n == 1){
            return n;
        }
        int[] dp = new int[n+1];
        dp[1] = 1;
        dp[2] = 2;
        for(int i=3; i<=n; i++){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
}

 

三、使用最小花费爬楼梯

https://leetcode.cn/problems/min-cost-climbing-stairs/?envType=problem-list-v2&envId=8At1GmaZ

   这道题是“最小花费爬楼梯”问题,属于典型的动态规划应用。我们定义状态 dp[i] 表示到达第 i 阶(第 i 层楼梯顶部)所需的最小花费。由于每次可以跨 1 或 2 阶,所以状态转移方程为:dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])

  初始化时,dp[0] = 0dp[1] = 0,表示从地面或第一阶出发不用花费。最终我们要求的是到达楼顶(即下标为 cost.length)的最小花费,因此返回 dp[n] 即可。该方法避免了重复计算,时间复杂度为 O(n),空间复杂度也为 O(n),是台阶类 DP 问题中的代表题型。

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        //这里顶楼应该是下标为cost.length+1
        //1.dp[i]: 达到第i层所需要的最低花费
        //2.dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
        //3.初始化
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 0;
        for(int i=2; i<=n; i++){
            dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
        }
        return dp[n];
    }
}
posted @ 2025-05-29 12:39  筱倩  阅读(264)  评论(0)    收藏  举报