动态规划-斐波那契数列

动态规划(Dynamic Programming, DP)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划通常用于求解最优化问题,如最短路径问题、背包问题、项目调度问题等。其核心思想是将待求解的问题分解成若干个简单的子问题,先求解子问题,然后从这些子问题的解得到原问题的解。动态规划会保存已解决的子问题的答案,从而避免重复计算,提高算法效率。

动态规划的基本步骤

  1. 定义状态
    首先,需要确定问题的状态表示,即如何描述一个子问题的解。状态通常是一个或多个变量的组合,用于表示子问题的当前进度或条件。

  2. 建立状态转移方程
    状态转移方程描述了如何从较小的子问题的解推导出较大子问题的解。它定义了如何根据前一个或多个状态来计算当前状态的值。

  3. 初始化边界条件
    确定状态转移方程的边界条件,即最小的子问题(通常是问题的起点或最简单的情况)的解。

  4. 计算顺序
    根据问题的性质,确定计算状态的顺序。这通常是从最简单的子问题开始,逐步计算更复杂的子问题,直到达到原问题的解。

  5. 优化(可选)
    在实际应用中,可能需要进一步优化动态规划算法,如通过记忆化搜索减少重复计算,或者利用数据结构(如线段树、树状数组等)来加速状态转移的计算。

示例1:斐波那契数列-爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

这是一个非常经典的动态规划问题,其中每个数是前两个数的和。我们可以使用动态规划来计算。

状态定义

  • dp[i] 表示到达第i个楼梯可以有的方法。

状态转移方程

  • dp[i] = dp[i-1] + dp[i-2](对于i > 1

边界条件

  • dp[0] = 0
  • dp[1] = 1

计算顺序

  • dp[0]dp[1]开始,依次计算dp[2]dp[3],直到dp[n]
class Solution {
public:
    int climbStairs(int n) {
        int a = 1, b = 1, sum;
        for(int i = 0; i < n - 1; i++){
            sum = a + b;
            a = b;
            b = sum;
        }
        return b;
    }
};

示例2:斐波那契数列-使用最小花费爬楼梯

为了解决这个问题,我们可以使用动态规划(Dynamic Programming, DP)的方法。动态规划是解决这类“最优解”问题的一种常用方法,特别是当问题可以分解为较小的、重叠的子问题时。

在这个问题中,我们可以定义一个数组 dp,其中 dp[i] 表示到达第 i 个台阶时的最低花费。根据题目描述,我们可以从第 0 个或第 1 个台阶开始,因此我们需要初始化 dp[0] = cost[0](如果可以从第 0 个台阶开始)和 dp[1] = cost[1](如果可以从第 1 个台阶开始)。但考虑到题目没有明确说明是否可以从第 0 个台阶开始,并且通常楼梯的起始台阶是下标为 1 的台阶,我们假设从第 1 个台阶开始,即 dp[1] = cost[1],并且如果数组 cost 的长度足够,dp[0] = cost[0](虽然它不会被直接使用,但为了完整性可以初始化)。

接下来,我们可以使用以下递推关系来计算 dp[i](对于 i >= 2):

dp[i]=min(dp[i−1]+cost[i−1],dp[i−2]+cost[i−2])

这个递推关系表示,到达第 i 个台阶的最低花费是到达前一个台阶(i-1)并支付其费用,或者到达前两个台阶(i-2)并支付其费用,然后加上当前台阶的费用,两者中的较小值。

最后,dp[n](其中 n 是 cost 数组的长度)将包含到达楼梯顶部的最低花费。

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        vector<int> dp(n + 1);
        dp[0] = dp[1] = 0;
        for (int i = 2; i <= n; i++) {
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[n];
    }
};

总结

动态规划是一种强大的算法设计技术,特别适用于那些具有重叠子问题和最优子结构特征的问题。通过合理定义状态、建立状态转移方程、初始化边界条件以及确定计算顺序,可以有效地解决复杂的最优化问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值