312. 戳气球

题目描述

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

解答

cpp 复制代码
class Solution {
public:
    int maxCoins(vector<int>& nums) {
        
        // 依次取最小的气球戳破
        // dp方法
        // 假设气球区间为开区间(i, j), 只能戳破i和j之间的气球,但两边(i和j)可被乘
        // 先不管前面怎么戳,只考虑最后一个被戳破的气球位置,【设最后一个被戳破气球位置是k】

        // dp[i][j] 表示(i, j) 区间可以获得的最大硬币数量
        // 开区间得到的硬币可由 dp[i][k] 和dp[k][j] 推导之
        // 则得到的金币数量为 total = dp[i][k] + val[i] * val[k] * val[j] + dp[k][j];

        int n = nums.size();
        // 实际元素在下标[1, n]位置中存放
        vector<vector<int>> dp(n + 2, vector<int>(n + 2, 0));
        // 创建一个辅助数组,首尾为1,便于操作
        vector<int> temp(n + 2);
        temp[0] = 1;
        temp[n + 1] = 1;

        for(int i = 1; i <= n; ++i)
        {
            temp[i] = nums[i - 1];
        }

        // dp由中间往两边推导
        // len 表示开区间长度, 对每一个区间长度循环
        for(int len = 3; len <= n + 2; len++)
        {
            // l 表示开区间左端点
            for(int l = 0; l <= n + 2 - len; l++)
            {
                // 判断区间内每个点作为最后一个戳破位置可得硬币
                for(int k = l + 1; k < l + len - 1; k++)
                {
                    int left = dp[l][k];
                    int right = dp[k][l + len - 1];
                    int sum = left + right + temp[k] * temp[l] * temp[l + len - 1];
                    dp[l][l + len - 1] = max(dp[l][l + len - 1], sum);
                }
            }
        }
        return dp[0][n + 1];
    }
};
相关推荐
浅川.2515 分钟前
STL专项:stack 栈
数据结构·stl·stack
YGGP1 小时前
【Golang】LeetCode 32. 最长有效括号
算法·leetcode
自然常数e1 小时前
字符函数和字符串函数
c语言·算法·visual studio
youngee111 小时前
hot100-56最小栈
数据结构
leaves falling2 小时前
c语言分数求和
算法
Das12 小时前
【机器学习】01_模型选择与评估
人工智能·算法·机器学习
星轨初途2 小时前
郑州轻工业大学2025天梯赛解题
c++·经验分享·笔记·算法·链表·剪枝
不忘不弃2 小时前
从字符串中提取数字
数据结构·算法
点云SLAM3 小时前
C++ 引用折叠(Reference Collapsing)和示例讲解说明
数据结构·c++·标准算法·完美转发·代码性能优化·c++ 引用折叠·typedef / using