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];
    }
};
相关推荐
Jay20021114 分钟前
【机器学习】30 基于内容的过滤算法
人工智能·算法·机器学习
冰西瓜6007 分钟前
分治(二)算法设计与分析 国科大
数据结构·算法
小小晓.15 分钟前
Pinely Round 2 (Div. 1 + Div. 2)
c++·算法
清风拂山岗 明月照大江24 分钟前
简单文件 IO 示例:使用系统调用读写文件
开发语言·c++·算法
Hcoco_me32 分钟前
大模型面试题15:DBSCAN聚类算法:步骤、缺陷及改进方向
算法·数据挖掘·聚类
AI绘画哇哒哒37 分钟前
AI 智能体长期记忆系统架构设计与落地实践
人工智能·学习·算法·ai·程序员·产品经理·转行
加藤不太惠1 小时前
【无标题】
java·数据结构·算法
金色旭光1 小时前
目标追踪算法+卡尔曼滤波原理+ByteTrack使用
算法
夏乌_Wx1 小时前
练题100天——DAY22:数字拼接+只出现一次的数字
java·数据结构·算法
listhi5201 小时前
MOEAD算法实现详解(基于Python与MATLAB)
python·算法·matlab