312. 戳气球

题目描述

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

现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1 和 i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1或 i + 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];
    }
};
相关推荐
Eyfcom11 分钟前
〖物联网终端实战 01〗UWB 室内高精度定位:仓储 AGV 与人员的厘米级轨迹追踪
物联网·算法·物流系统·快递系统·跨境物流快递系统·物联网终端实战
bro_Java6661 小时前
《排序的底层逻辑:比较、交换与分治》
java·算法·排序算法
爱喝雪碧的可乐1 小时前
MATLAB
开发语言·算法·matlab
叼烟扛炮2 小时前
Linux 学习笔记(六十):单线程的逆袭——epoll 高并发服务器实战
linux·服务器·网络·笔记·学习·算法
careathers2 小时前
【数据结构】基于比较的排序算法 - 交换排序
数据结构·算法·排序算法
H.莓飛3 小时前
【C++】【STL】vector_OJ题
linux·服务器·开发语言·数据结构·c++·visual studio
Rabitebla3 小时前
【Linux操作系统】进程篇(十一):进程程序替换——从底层原理到 exec 函数族
linux·服务器·c++·笔记·学习·算法
tellmewhoisi3 小时前
深度学习0:数学知识:正态分布1
人工智能·深度学习·算法
-梅3 小时前
算法(1) 动态规划
算法·动态规划
青少儿编程课堂4 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:Bellman-Ford与SPFA含负权最短路及负环检测全解析
c++·python·算法·bfs·信息学竞赛