首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >动态规划

动态规划

原创
作者头像
半月无霜
发布2025-02-10 21:29:18
发布2025-02-10 21:29:18
3350
举报
文章被收录于专栏:半月无霜半月无霜

一、介绍

动态规划是什么算法,顾名思义就是动态地进行计算,下面来看看百度词条的解释

动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题、最短路径问题和复杂系统可靠性问题等中取得了显著的效果 。

以上是动态规划算法的解释,那么如何将应用到实际问题中呢

或者说该算法的核心是什么,我们将采用何种思维去使用这个算法,进行破题

它的核心就是将问题分解为一系列子问题,并通过记忆化或递推的方式求解子问题,从而得到原始问题的解。

那么不多说,我们先看看下面这个问题

二、斐波那契数列

首先,斐波那契数列大家非常熟悉,也能马上能想到它的一个方法解;如下

代码语言:javascript
复制
package com.banmoon.arithmetic;
​
public class Fibonacci {
​
    public static long fibonacci(int n) {
        if (n == 0) {
            return 0;
        } else if (n == 1) {
            return 1;
        } else {
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
​
}

可以看到非常简单,这使用了递归

传入n=5,结果为5

传入n=10,结果为55

但有没有想过,n10 = n9 + n8,而n9n8哪里来的,都是各自的递归函数底层传递回来的

也就是说这种递归方法,会调用很多很多次fibonacci(0)fibonacci(1)...

你传入的n越大,最底下的就会调用更多次,造成了浪费

正好,我们只需要将以前计算过的值存储起来,在后面进行取用即可

代码语言:javascript
复制
package com.banmoon.arithmetic;
​
import java.util.HashMap;
import java.util.Map;
​
public class Fibonacci {
​
    private static Map<Integer, Long> map = new HashMap<>();
​
    public static long fibonacci(int n) {
        if (n == 0) {
            return 0;
        } else if (n == 1) {
            return 1;
        } else if (map.containsKey(n)) {
            return map.get(n);
        } else {
            long result = fibonacci(n - 1) + fibonacci(n - 2);
            map.put(n, result);
            return result;
        }
    }
​
}

可以看到我们这边使用了一个map,用来存储以前计算过的值,如果后面需要取用,那么直接在map中进行取值即可

有效果了,但还不够;因为这一块还需要进行递归地从map中获取,那么有没有办法不从map中获取呢

答案是有的,我们可以直接使用数组,存储我们的斐波拉契数列,新答案如下

代码语言:javascript
复制
package com.banmoon.arithmetic;
​
public class Fibonacci {
​
    public static long fibonacci(int n) {
        // 创建一个数组来存储子问题的解,初始值为0
        long[] dp = new long[n + 1];
        // 初始化前两个数的值
        dp[0] = 0;
        dp[1] = 1;
        // 从第三个数开始迭代计算
        for (int i = 2; i <= n; i++) {
            // 通过状态转移方程计算当前数的值
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        // 返回第n个数的值
        return dp[n];
    }
​
}

上面就创建一个数组dp来保存子问题的解,避免了重复计算的问题,在上一个计算完成后,存储起来,作为材料提供给下一个问题去使用。

三、最后

大家可以多去力扣看看动态规划的具体问题,上面只是一个简单的示例,实际的动态规划问题可能会更复杂。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、介绍
  • 二、斐波那契数列
  • 三、最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档