leetcode 312.戳气球

题目链接:leetcode 312

1.题目

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

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

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

2.示例

1)示例 1:
输入:nums = [3,1,5,8]
输出:167
解释:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 315 + 358 + 138 + 181 = 167

2)示例 2:
输入:nums = [1,5]
输出:10

3)提示:
n == nums.length
1 <= n <= 300
0 <= nums[i] <= 100

3.分析

我们考虑f[i][j]是一个左右都不包含i,j的区间,这个区间气球都爆了的最大值如何计算呢?假设k是(i,j)区间内的一个点,它是最后一个被引爆的气球,那么f[i][j]=max(f[i][j],f[i][k]+f[k][j]+nums[i]*nums[k]*nums[j]),这道题目就转化成了一道简单的区间dp问题

4.代码

class Solution {
public:
    int f[310][310];
    int maxCoins(vector<int>& nums) {
        vector<int> nums1;
        nums1.push_back(1);
        for(int i=0;i<nums.size();i++)
            nums1.push_back(nums[i]);nums1.push_back(1);
        memset(f,0,sizeof(f));
        for(int i=3;i<=nums1.size();i++)
            for(int j=0;j+i-1<nums1.size();j++){
                int st=j,ed=i+j-1;
                for(int k=st+1;k<ed;k++){
                    f[st][ed]=max(f[st][ed],f[st][k]+f[k][ed]+nums1[st]*nums1[ed]*nums1[k]);
                } 
            }
        return f[0][nums1.size()-1];
    }
};

你可能感兴趣的:(leetcode,leetcode,算法,数据结构)