返回

LeetCode 312. Burst Balloons(Python): 用心领悟动态规划的魅力

后端







## LeetCode 312. Burst Balloons:一种巧妙的动态规划算法

### 问题

给定一个由 `n` 个气球组成的数组 `nums`,其中 `nums[i]` 是第 `i` 个气球的价值。

现在,您需要依次选择并爆破气球,使您可以获得最大总价值。

每次爆破一个气球都会使得相邻两个气球的价值加倍。

例如,若 `nums = [3, 1, 5, 8]`,您可以选择:

- 爆破气球 `3`,得到价值 `3`。
- 爆破气球 `5`,得到价值 `5 * 2 = 10`。
- 爆破气球 `8`,得到价值 `8 * 2 = 16`。

您的总价值为 `3 + 10 + 16 = 29`。

### 动态规划算法

可以使用动态规划算法来解决此问题。

首先,定义一个数组 `dp`,其中 `dp[i][j]` 表示从第 `i` 个气球到第 `j` 个气球的最佳价值。

然后,可以根据以下公式计算 `dp[i][j]`:

dp[i][j] = max(dp[i][j-1], dp[i+1][j], nums[i] * nums[j] + dp[i+1][j-1])


其中:

- `dp[i][j-1]` 表示从第 `i` 个气球到第 `j-1` 个气球的最佳价值。
- `dp[i+1][j]` 表示从第 `i+1` 个气球到第 `j` 个气球的最佳价值。
- `nums[i] * nums[j] + dp[i+1][j-1]` 表示爆破第 `i` 个和第 `j` 个气球,然后爆破从第 `i+1` 个到第 `j-1` 个气球的最佳价值。

### Python 代码实现

以下是使用 Python 实现的动态规划算法:

```python
def maxCoins(nums):
    n = len(nums)
    nums = [1] + nums + [1]

    dp = [[0] * (n + 2) for _ in range(n + 2)]

    for i in range(n - 1, -1, -1):
        for j in range(i + 1, n + 2):
            for k in range(i + 1, j):
                dp[i][j] = max(dp[i][j], dp[i][k] + dp[k][j] + nums[i] * nums[k] * nums[j])

    return dp[0][n + 1]

复杂度分析

动态规划算法的时间复杂度为 O(n^3),其中 n 是气球的数量。

空间复杂度为 O(n^2),因为我们需要存储 dp 数组。