动态规划(Dynamic Programming,简称DP)是一种解决问题的算法设计技术,通常用于优化问题。它通过将问题分解为更小的子问题,并解决这些子问题,然后合并它们的解决方案来解决原始问题。动态规划通常用于具有重叠子问题和最优子结构性质的问题。
动态规划的主要思想是避免重复计算,通过将中间结果存储起来,以便后续直接使用,从而提高效率。这种思想在递归过程中特别有用,因为递归经常会重复计算相同的子问题。
解决动态规划问题通常包括以下步骤:
定义子问题: 将原问题分解为规模较小的子问题。这有助于建立递归关系,也是动态规划的基础。
建立状态转移方程: 确定问题的状态,并找到状态之间的转移关系。状态转移方程描述了如何从一个状态过渡到另一个状态,这是解决问题的关键。
初始化: 初始化问题的边界状态。这是问题规模较小时的基本情况,它为递归的起点提供了必要的信息。
计算顺序: 确定计算状态的顺序。通常,动态规划问题可以按照自底向上或自顶向下的方式进行计算。
计算最终结果: 使用已计算的子问题的结果来计算原问题的解决方案。这通常是在状态转移方程中描述的最终状态。
下面是一个简单的动态规划问题的例子,以说明这些步骤:
问题: 计算斐波那契数列的第n项。
定义子问题: 斐波那契数列的第n项可以定义为前两项的和,因此问题可以分解为计算前两项的和。
建立状态转移方程: 设F(n)表示斐波那契数列的第n项,则F(n) = F(n-1) + F(n-2)。
初始化: F(0) = 0, F(1) = 1 是问题规模较小时的基本情况。
计算顺序: 从底向上计算,先计算 F(2),然后计算 F(3),以此类推。
计算最终结果: 最终结果是 F(n)。
在实际应用中,动态规划可以解决各种问题,例如最短路径问题、背包问题等。每个问题都需要根据具体情况定义子问题、建立状态转移方程,并按照合适的计算顺序进行求解。
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 1:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 400
Related Topics
数组
动态规划
首先看到求最高金额,我们就应该往动态规划上面去想(都是套路,别问我为什么)。当然也可以不想先用递归暴力解题,最终肯定是超时,这个时候我们自然而然会想到动态规划。
既然要用动态规划解题,我们肯定会按照动态规划的套路去解题。
根据切分子问题来找动态转移方程: