戳气球的最大得分问题(基础版本)
字数 1163 2025-11-19 06:41:18

戳气球的最大得分问题(基础版本)

题目描述:
给定一个长度为n的数组nums,代表n个气球,每个气球上标有一个数字。现在你需要戳破所有的气球。当你戳破第i个气球时,你可以获得nums[left] × nums[i] × nums[right]的分数,其中left和right代表与第i个气球相邻的气球。戳破气球i后,气球left和气球right会变成相邻的气球。

求戳破所有气球能获得的最大分数。

解题过程:

  1. 问题分析:
  • 当我们戳破一个气球时,得分取决于该气球和其左右相邻气球的数值
  • 戳破气球后,相邻关系会发生变化,这会影响后续戳气球的得分
  • 我们需要找到一个戳气球的顺序,使得总得分最大化
  1. 关键思路:
  • 考虑逆向思维:不是考虑"先戳哪个气球",而是考虑"最后戳哪个气球"
  • 当我们确定最后一个戳破的气球时,它左右两边的气球是相互独立的子问题
  • 在最后一个气球被戳破时,它的左边和右边边界是确定的
  1. 状态定义:
  • 定义dp[i][j]表示戳破区间(i, j)内所有气球能获得的最大分数
  • 注意:这里i和j是开区间边界,不包含在戳破范围内
  • 我们在原数组首尾各添加一个值为1的虚拟气球,表示边界
  1. 状态转移方程:
  • 对于区间(i, j),我们枚举最后一个被戳破的气球k,其中i < k < j
  • 当k是最后一个被戳破的气球时,得分为:
    dp[i][k] + dp[k][j] + nums[i] × nums[k] × nums[j]
  • 状态转移方程:
    dp[i][j] = max(dp[i][j], dp[i][k] + dp[k][j] + nums[i] × nums[k] × nums[j])
    其中k的取值范围是i+1到j-1
  1. 初始化:
  • 当区间长度小于等于1时,dp[i][j] = 0(没有气球可戳)
  • 其他情况初始化为0
  1. 计算顺序:
  • 按区间长度从小到大计算
  • 先计算长度小的区间,再计算长度大的区间
  1. 算法步骤:
  • 在nums首尾各添加一个1,得到新数组arr
  • 初始化dp数组,大小为(n+2)×(n+2),初始值为0
  • 枚举区间长度len从2到n+1(因为添加了边界)
  • 对于每个区间长度,枚举区间左端点i
  • 计算区间右端点j = i + len
  • 如果j > n+1,跳过
  • 枚举分割点k从i+1到j-1
  • 更新dp[i][j] = max(dp[i][j], dp[i][k] + dp[k][j] + arr[i] × arr[k] × arr[j])
  • 最终结果存储在dp[0][n+1]中
  1. 时间复杂度:O(n³),空间复杂度:O(n²)

这个解法通过逆向思考和区间DP的思想,将复杂的气球戳破顺序问题转化为相对简单的子问题组合,从而高效地求解最大得分。

戳气球的最大得分问题(基础版本) 题目描述: 给定一个长度为n的数组nums,代表n个气球,每个气球上标有一个数字。现在你需要戳破所有的气球。当你戳破第i个气球时,你可以获得nums[ left] × nums[ i] × nums[ right ]的分数,其中left和right代表与第i个气球相邻的气球。戳破气球i后,气球left和气球right会变成相邻的气球。 求戳破所有气球能获得的最大分数。 解题过程: 问题分析: 当我们戳破一个气球时,得分取决于该气球和其左右相邻气球的数值 戳破气球后,相邻关系会发生变化,这会影响后续戳气球的得分 我们需要找到一个戳气球的顺序,使得总得分最大化 关键思路: 考虑逆向思维:不是考虑"先戳哪个气球",而是考虑"最后戳哪个气球" 当我们确定最后一个戳破的气球时,它左右两边的气球是相互独立的子问题 在最后一个气球被戳破时,它的左边和右边边界是确定的 状态定义: 定义dp[ i][ j ]表示戳破区间(i, j)内所有气球能获得的最大分数 注意:这里i和j是开区间边界,不包含在戳破范围内 我们在原数组首尾各添加一个值为1的虚拟气球,表示边界 状态转移方程: 对于区间(i, j),我们枚举最后一个被戳破的气球k,其中i < k < j 当k是最后一个被戳破的气球时,得分为: dp[ i][ k] + dp[ k][ j] + nums[ i] × nums[ k] × nums[ j ] 状态转移方程: dp[ i][ j] = max(dp[ i][ j], dp[ i][ k] + dp[ k][ j] + nums[ i] × nums[ k] × nums[ j ]) 其中k的取值范围是i+1到j-1 初始化: 当区间长度小于等于1时,dp[ i][ j ] = 0(没有气球可戳) 其他情况初始化为0 计算顺序: 按区间长度从小到大计算 先计算长度小的区间,再计算长度大的区间 算法步骤: 在nums首尾各添加一个1,得到新数组arr 初始化dp数组,大小为(n+2)×(n+2),初始值为0 枚举区间长度len从2到n+1(因为添加了边界) 对于每个区间长度,枚举区间左端点i 计算区间右端点j = i + len 如果j > n+1,跳过 枚举分割点k从i+1到j-1 更新dp[ i][ j] = max(dp[ i][ j], dp[ i][ k] + dp[ k][ j] + arr[ i] × arr[ k] × arr[ j ]) 最终结果存储在dp[ 0][ n+1 ]中 时间复杂度:O(n³),空间复杂度:O(n²) 这个解法通过逆向思考和区间DP的思想,将复杂的气球戳破顺序问题转化为相对简单的子问题组合,从而高效地求解最大得分。