webVueBlog / LeetCode-HOT-100

力扣 (LeetCode) 🔥LeetCode HOT 100

Home Page:https://webvueblog.github.io/LeetCode-HOT-100/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

312. 戳气球

webVueBlog opened this issue · comments

312. 戳气球

Description

Difficulty: 困难

Related Topics: 数组, 动态规划

n 个气球,编号为0n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。

求所能获得硬币的最大数量。

示例 1:

输入:nums = [3,1,5,8]
输出:167
解释:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins =  3*1*5    +   3*5*8   +  1*3*8  + 1*8*1 = 167

示例 2:

输入:nums = [1,5]
输出:10

提示:

  • n == nums.length
  • 1 <= n <= 300
  • 0 <= nums[i] <= 100

Solution

Language: JavaScript

/**
 * @param {number[]} nums
 * @return {number}
 */
/*
[3, 1, 5, 8]
 0, 1, 2, 3

 dp[0][1] + nums[-1] * nums[2] * nums[len] + dp[3][3]
 dp[0][1] = ?
  dp[0][0] =
  dp[1][1] =
 dp[3][3] = ?

 dp[0][3][?] = Math coin

 dp[0][3][k] = dp[0][k] + dp[k][3] + nums[0] * nums[k] * nums[3]
 dp[i][j][k] = dp[i][k] + dp[k][j] + nums[i] * nums[k] * nums[j]
 */
var maxCoins = function(nums) {
    nums = [1, ...nums, 1]
    let len = nums.length
    let dp = new Array(len).fill(0).map(_ => new Array(len).fill(0))
    // 起始位置
    for (let i = len - 3; i >= 0; i--) {
        // 结束位置
        for (let j = i + 2; j < len; j++) {
            for (let k = i + 1; k < j; k++) {
                dp[i][j] = Math.max(
                    dp[i][j],
                    dp[i][k] + dp[k][j] + nums[i] * nums[k] * nums[j]
                )
            }
        }
    }
    return dp[0][len-1]
}