行业知识
前端算法之动态规划
- 动���规划
- 动态规划解决什么问题
- 最短路径问题:
- 背包问题:
- 最长公共子序列问题:
- 最大子数组和问题:
- 调度问题:
- 编辑距离问题:
- 矩阵链乘法问题:
- 动态规划例子1
- 下面是JavaScript实现代码:
- 动态规划例子2 – 爬楼梯
- 动态规划例子3 – 使用最小花费爬楼梯
动态规划
动态规划(Dynamic Programming)是一种算法思想,通常用于解决一些优化问题和最优解问题。
()它的基本思路是 将一个大问题拆分成若干个小问题,先解决小问题,再合并得到原问题的解。
动态规划算法通常包括以下几个步骤:
()-
定义状态:将原问题拆分成若干个子问题,并将子问题中需要求解的参数定义为状态。
-
状态转移方程:通过状态之间的转移得到更大规模的子问题的解,从而逐步推导出原问题的解。
-
边界条件:确定最小的子问题,即边界条件。
-
计算顺序:按照子问题的规模从小到大依次计算,确保每一个子问题的解都已经求出。
动态规划算法的时间复杂度通常为O(n^2),与子问题的规模有关。
它在求解最优解问题、背包问题、最长公共子序列等问题中广泛应用。
动态规划解决什么问题
动态规划是一种解决优化问题的算法思想,它通过将问题分解为子问题,并利用子问题的解来构建原问题的解。
动态规划通常适用于具有重叠子问题和最优子结构性质的问题。
动态规划可以解决很多问题,包括但不限于以下几类:
最短路径问题:
如在一个有向图中找到两个节点之间的最短路径。
背包问题:
如在给定容量的背包中选择一组物品使得价值最大化,同时要保持总重量不超过背包容量。
最长公共子序列问题:
如给定两个序列,找到它们最长的共同子序列。
最大子数组和问题:
如找到一个数组中连续子数组的最大和。
调度问题:
如在给定一组任务和资源的情况下,确定任务的最佳调度顺序以最小化完成时间或最大化资源利用率。
编辑距离问题:
如找到将一个字符串转换为另一个字符串所需的最少编辑操作次数(插入、删除、替换)。
矩阵链乘法问题:
如找到一组矩阵相乘的最佳顺序,使得总乘法次数最少。
通过合理设计状态转移方程和使用适当的技巧,可以有效地利用动态规划算法解决各种复杂的优化问题。
更多详细内容,请微信搜索“前端爱好者“, 戳我 查看 。
动态规划例子1
以下是使用JavaScript实现动态规划的一个例子,
假设有一个长度为n的数组A,需要从中选出一些数,使得它们的和最大,但是选出的数不能相邻。
这就是一个典型的最优解问题,可以使用动态规划算法来求解。
首先定义状态: 设f(i)为前i个数中选取不相邻数能够获得的最大和。那么问题的解就是f(n)。
状态转移方程: 对于前i个数,如果选第i个数,则不能选第i-1个数,所以其最大和为f(i-2)+A[i];如果不选第i个数,则其最大和为f(i-1),因此f(i)应该为这两者中的最大值。
边界条件: 对于前0个数,其最大和为0,即f(0)=0;对于前1个数,其最大和为A[0],即f(1)=A[0]。
计算顺序: 按照子问题的规模从小到大依次计算,确保每一个子问题的解都已经求出。因此,可以使用循环从2开始逐步计算f(2)、f(3)、…、f(n),最终得到f(n)即为问题的解。
下面是JavaScript实现代码:
function maxSum(A) { let n = A.length; if (n == 0) { return 0; } else if (n == 1) { return A[0]; } else { let f = new Array(n + 1); f[0] = 0; f[1] = A[0]; for (let i = 2; i f[i] = Math.max(f[i - 2] + A[i - 1], f[i - 1]); } return f[n]; }}// 示例let A = [1, 2, 4, 1, 7, 8, 3];let result = maxSum(A);console.log(result); // 输出15 // 1. 定义子问题 // 2. 根据要执行的问题,重复执行子问题 // 3. 找到边界 // dp[0] = 1 一次爬一到两个台阶,一次爬一阶梯是一步 // dp[1] = 1 爬第二节台阶也是一步 let dp = [1,1] // dp[i] = dp[i-1] + dp[i-2] -- dp[i]代表当前台阶位置, // 因为之前定义了第零阶梯和第一阶梯,所以,要从第二阶梯开始 for(let i = 2; i dp[i] = dp[i-1] + dp[i-2] // 子问题的标准:上一个点与下一个节点的关系 } return dp[n]}; cost.push(0) // 不爬台阶,费用为0,也就是边界为0 let dp = [] let n = cost.length dp[0] = cost[0] dp[1] = cost[1] // 当前台阶费用,取决于上一级台阶费用【一次爬一个】或者上上节台阶费用【一次爬两个台阶】加上当前费用 // dp[i] = Math.min(dp[i-1],dp[i-2]) + cost[i] for(let i = 2; i -
- 动态规划解决什么问题
下一篇:无敌新服务器怎么进?