动态规划

1、动态规划概述

动态规划是一种解决多阶段决策问题的数学优化方法。它将原问题分解成若干个子问题,
通过解决子问题只需解决一次并将结果保存下来,从而避免了重复计算,提高了算法效率。

通俗来讲,动态规划算法是解决一类具有重叠子问题和最优子结构性质的问题的有效方法。其基本原理是将大问题分解为小问题,通过保存中间结果来避免重复计算,从而提高算法的效率。

动态规划主要包括两个要素:最优子结构和重叠子问题。

2、基本概念

  1. 最优子结构(Optimal Substructure): 问题的最优解可以由其子问题的最优解递归地构建而成。
  2. 重叠子问题(Overlapping Subproblems): 问题可以被分解成若干个相同的子问题,这些子问题会被反复解决。
  3. 状态转移方程(State Transition Equation): 用于描述问题的状态和状态之间的关系,通过状态的转移得到最终问题的解。

3、动态规划算法步骤

1.定义状态:确定问题的状态,将大问题分解为子问题,并确定子问题所对应的状态。
2.建立状态转移方程:根据题目要求或者问题的定义,建立子问题之间的递推关系。
3.初始化:确定初始状态的值。
4.递推求解:根据状态转移方程,自底向上地求解问题,直到得到最终的结果。
5.输出结果:根据最终的状态求解结果。

4、区别

分治和动态规划

共同点:都是将问题分解成子问题,然后合并子问题的解得到原问题。
区别:分治分出来的子问题是不重叠的,如归并排序和快速排序(分别处理左右排序,然后将左右序列结果合并),分治解决的问题不一定是最优化问题。
动态规划解决的问题拥有重叠子问题,且一定是最优化问题。

贪心和动态规划

共同点:都要求问题拥有最优子结构。
贪心:整个过程以单链的流水方式进行,显然这种“最优的选择”的正确性需要用归纳法证明。例如数塔问题,贪心从最上层开始,每次选择左下或右下较大的那个,一直到最底层得到结果,显然这不一定可以得到最优解。
动态规划:无论采用自底向上还是自顶向下的方法,都是从边界向上得到最优解,它总是会考虑所有子问题,并选择继承能得到最优结果那个,对于暂时没被继承的子问题,由于重叠子问题的存在,后期可能会再次考虑它,
因此还有机会成为全局最优的一部分,不需要放弃。

5、应用

动态规划广泛应用于解决一些优化问题,如最短路径问题、最长公共子序列、背包问题等。以下是一些常见的应用场景:

最短路径问题: 比如 Dijkstra 算法和 Floyd-Warshall 算法。

背包问题: 包括 0/1 背包问题和背包问题的变种。

最长公共子序列: 求解两个序列的最长公共子序列的长度。

字符串编辑距离: 计算两个字符串之间的最小编辑操作次数,包括插入、删除和替换。

最大子数组和: 求解数组中连续子数组的最大和。

示例:假设有一个数组 nums,求解其连续子数组的最大和

动态规划解法:

定义状态: 设 dp[i] 为以 nums[i] 结尾的连续子数组的最大和。

状态转移方程: dp[i] = max(dp[i-1] + nums[i], nums[i]),即当前位置的最大和要么是之前的最大和加上当前元素,要么是当前元素本身。

初始化: dp[0] = nums[0],数组的第一个元素作为初始值。

遍历: 从数组的第二个元素开始遍历,更新 dp[i]。

最终结果: 最大的 dp[i] 即为所求。

 

posted @ 2024-04-12 16:51  taohuaxiaochunfeng  阅读(34)  评论(0编辑  收藏  举报