戳气球的最大得分问题(基础版本)
字数 1170 2025-11-11 23:38:30

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

题目描述:
给定一个长度为n的数组nums,表示一排气球,每个气球上标有一个数字。当你戳破一个气球i时,你可以获得nums[left] × nums[i] × nums[right]的分数,其中left和right是气球i相邻的左右气球。戳破气球i后,left和right变成相邻。求戳破所有气球能获得的最大分数。

解题过程:

  1. 问题分析:
  • 当我们戳破一个气球时,得分取决于该气球和其左右相邻气球的值
  • 戳破气球后,相邻关系会改变,这会影响后续戳破的得分
  • 我们需要找到戳破气球的顺序,使得总得分最大
  1. 关键思路转换:
  • 与其考虑"先戳破哪个气球",不如考虑"最后一个戳破哪个气球"
  • 如果气球k是最后一个被戳破的,那么:
    • 在戳破k之前,区间[0, k-1]和[k+1, n-1]的气球已经被戳破
    • 戳破k时,它的左右邻居就是整个区间的边界
  1. 动态规划定义:
  • 定义dp[i][j]表示戳破区间(i, j)内所有气球能获得的最大分数
  • 注意:这里区间是开区间(i, j),不包括i和j位置的气球
  • 我们在原数组两端各添加一个值为1的气球,即新数组为[1, nums[0], nums[1], ..., nums[n-1], 1]
  1. 状态转移方程:
  • 对于区间(i, j),枚举最后一个戳破的气球k(i < k < j)
  • 戳破k时的得分 = nums[i] × nums[k] × nums[j]
  • 总得分 = 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])
  1. 初始化:
  • 当区间长度小于3时(即i+1 ≥ j),区间内没有气球,dp[i][j] = 0
  1. 计算顺序:
  • 按区间长度从小到大计算
  • 先计算长度为3的区间,然后长度为4,直到长度为n+2
  1. 算法步骤:
  • 创建新数组arr = [1] + nums + [1],长度为n+2
  • 初始化dp为(n+2)×(n+2)的二维数组,初始值为0
  • 对于区间长度len从3到n+2(因为包含两端的虚拟气球)
  • 对于区间起点i从0到n+2-len
  • 计算区间终点j = i + len - 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²)
戳气球的最大得分问题(基础版本) 题目描述: 给定一个长度为n的数组nums,表示一排气球,每个气球上标有一个数字。当你戳破一个气球i时,你可以获得nums[ left] × nums[ i] × nums[ right ]的分数,其中left和right是气球i相邻的左右气球。戳破气球i后,left和right变成相邻。求戳破所有气球能获得的最大分数。 解题过程: 问题分析: 当我们戳破一个气球时,得分取决于该气球和其左右相邻气球的值 戳破气球后,相邻关系会改变,这会影响后续戳破的得分 我们需要找到戳破气球的顺序,使得总得分最大 关键思路转换: 与其考虑"先戳破哪个气球",不如考虑"最后一个戳破哪个气球" 如果气球k是最后一个被戳破的,那么: 在戳破k之前,区间[ 0, k-1]和[ k+1, n-1 ]的气球已经被戳破 戳破k时,它的左右邻居就是整个区间的边界 动态规划定义: 定义dp[ i][ j ]表示戳破区间(i, j)内所有气球能获得的最大分数 注意:这里区间是开区间(i, j),不包括i和j位置的气球 我们在原数组两端各添加一个值为1的气球,即新数组为[ 1, nums[ 0], nums[ 1], ..., nums[ n-1], 1 ] 状态转移方程: 对于区间(i, j),枚举最后一个戳破的气球k(i < k < j) 戳破k时的得分 = nums[ i] × nums[ k] × nums[ j ] 总得分 = 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 ]) 初始化: 当区间长度小于3时(即i+1 ≥ j),区间内没有气球,dp[ i][ j ] = 0 计算顺序: 按区间长度从小到大计算 先计算长度为3的区间,然后长度为4,直到长度为n+2 算法步骤: 创建新数组arr = [ 1] + nums + [ 1 ],长度为n+2 初始化dp为(n+2)×(n+2)的二维数组,初始值为0 对于区间长度len从3到n+2(因为包含两端的虚拟气球) 对于区间起点i从0到n+2-len 计算区间终点j = i + len - 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²)