动态规划算法入门篇:何为动态规划?

        动态规划(Dynamic Programming, DP)是一种用于求解最优化问题的算法,其核心思想是通过将复杂问题分解为多个相互重叠的子问题,构建最优解与这些子问题之间的递推关系,避免重复计算,高效得出全局最优解

基本原理

        1. 最优子结构:问题的最优解可以被分解为其子问题的最优解。如果一个问题的最优解包含了其子问题的最优解,那么该问题具有最优子结构性质。

         2. 重叠子问题:在求解一个问题的过程中,需要多次解决相同的子问题。为了避免重复计算,动态规划会将子问题的解存储起来,以便在需要时直接使用,而不是重新计算。

        由此可见,动态规划算法适用于求解具有最优子结构和重叠子问题特性的最优化问题,可以显著减少问题的计算量,提高算法效率。

求解步骤

        1. 定义状态:明确定义问题的状态。状态是问题的关键信息,可以描述问题的不同阶段。问题的状态应该包含问题的所有关键信息,以便通过状态来表示问题的不同子问题。

        2. 建立状态转移方程:基于最优子结构性质,建立问题状态之间的递推关系,得到状态转移方程。状态转移方程描述了问题的最优解与其子问题之间的关系,通常使用递归或迭代方式表示。

        3. 确定边界条件:边界条件是问题的初始状态,即最小规模的子问题的解。边界条件是递归或递推过程中的终止条件或起始条件,确保问题能够在最小规模时得到解决。

        4. 求解最优解或最优值:通过状态转移方程,从初始状态出发,自底向上求解问题的最优解。或者自顶向下使用基于记忆功能的动态规划方法将已计算的子问题的解存储起来,以避免重复计算。基于记忆功能的动态规划方法是动态规划中常用的优化技巧,可以显著提高算法的效率。

实例分析

        爬楼梯问题:考虑有n阶楼梯,每次可以上1阶或2阶,要找出所有到达顶层的方法总数。这个问题要求解的最优值是”最多的方法数“。

        1. 定义状态:这里的状态变量就可以定义为到第i阶楼梯的不同走法数目,记作dp[i]。

        2. 建立状态转移方程:我们需要找到爬到第i阶的方式与其之前的状态之间的关系。由于每次可以爬1阶或2阶,爬到第i阶的方式可以由爬到第i-1阶和爬到第i-2阶的方式累加得到。因此,状态转移方程为:

dp[1] = 1   // 当该楼梯只有1阶时有一种方式,直接上一阶楼梯
dp[2] = 2   // 当该楼梯只有2阶时有两种方式,分别是一阶一阶上和一次性上两阶的方式
dp[i] = dp[i-1] + dp[i-2] (对于 i > 2)  // 当该楼梯大于2阶时

        3. 确定边界条件:在上述爬楼梯问题中,我们已知dp[1]和dp[2]的值,这是递推的起始点,就是我们的边界条件。

        4. 求解最优值:初始化一个长度为n+1的数组dp,其中dp[0]设为0(没有楼梯可上),dp[1]和dp[2]根据边界条件初始化。从第三阶楼梯开始,按照状态转移方程填充整个数组。

        下面是爬楼梯问题的c语言代码:

#include <stdio.h>
int climbStairs(int n) {
    if (n == 1) {
        return 1;
    }
    if (n == 2) {
        return 2;
    }
    // 定义数组,存储中间值
    int dp[n + 1];
    dp[1] = 1;
    dp[2] = 2;
    int i; 
    // 根据状态转移方程填充数组
    for (i = 3; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    // 返回结果
    return dp[n];
}
int main() {
    int n = 5;  // 可以根据需要设置不同的楼梯阶数
    printf("爬楼梯方法总数: %d\n", climbStairs(n));
    return 0;
}
// 输出:
// 爬楼梯方法总数: 8

动态规划与其他算法的对比

        分治法:分治法将大问题分解成多个相同的小问题,然后递归求解小问题,最后合并得到原问题的答案。与动态规划相比,分治法中子问题是相互独立的,而动态规划中子问题存在重叠性

        贪心算法:贪心算法每一步都采取当前看起来最优的选择,不考虑未来决策的影响。而动态规划则会综合考虑之前的所有决策对当前结果的影响,确保全局最优

实战练习

        动态规划算法求解斐波那契数列问题:

        斐波那契数列是这样一个数列,其前两个数字都是 1,从第三项开始,每一项都是前两项之和。斐波那契数列的前几项为 1, 1, 2, 3, 5, 8, 13, 21, ...。现在要求使用动态规划算法计算第n个斐波那契数。

写在最后

        接下来我们将继续深入探讨动态规划算法,介绍并求解最长公共子序列、最短路径问题、背包问题等一系列经典的最优化问题。

        敬请期待!

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值