动态规划是什么算法,顾名思义就是动态地进行计算,下面来看看百度词条的解释
动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题、最短路径问题和复杂系统可靠性问题等中取得了显著的效果 。
以上是动态规划算法的解释,那么如何将应用到实际问题中呢
或者说该算法的核心是什么,我们将采用何种思维去使用这个算法,进行破题
它的核心就是将问题分解为一系列子问题,并通过记忆化或递推的方式求解子问题,从而得到原始问题的解。
那么不多说,我们先看看下面这个问题
首先,斐波那契数列大家非常熟悉,也能马上能想到它的一个方法解;如下
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,而n9、n8哪里来的,都是各自的递归函数底层传递回来的
也就是说这种递归方法,会调用很多很多次fibonacci(0),fibonacci(1)...
你传入的n越大,最底下的就会调用更多次,造成了浪费
正好,我们只需要将以前计算过的值存储起来,在后面进行取用即可
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中获取呢
答案是有的,我们可以直接使用数组,存储我们的斐波拉契数列,新答案如下
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 删除。