题解——Leetcode 312. Burst Balloons 难度:Hard

Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.

Find the maximum coins you can collect by bursting the balloons wisely.

Note: 
(1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
(2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

Example:

Given [3, 1, 5, 8]

Return 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

给定n个气球,每个气球对应一个数组中的元素,你需要将所有气球扎破,每扎破一个气球i,你将得到nums[left] * nums[i] * nums[right]个硬币,left和right为扎破气球左右相邻的气球,当气球I被扎破后,气球left和right就相邻了。

当扎破最左边的气球时,nums[left] = 1,当扎破最右边的气球时,nums[right] = 1。

本题可以采用动态规划的思想,rangeValues[i][j]代表扎破[i, j]范围内的气球所得到的最多硬币数,在nums头尾分别插入元素1,rangeValues[0][N]即为本题所求。

start、end分别表示range内最左和最右的下标,考虑最后一个被扎破的气球final,扎破它能得到nums[start-1] * nums[final] * nums[end+1]个硬币,之前扎破气球得到硬币rangeValue[start][final-1] + rangeValue[final+1][end],如果相加后coins大于bestCoins,则将coins赋值给bestCoins,那么bestCoins即为扎破[start, end]范围内的气球所得到的最多硬币数。

class Solution {
public:
    int maxCoins(vector<int>& nums) {
        int N = nums.size();
        nums.insert(nums.begin(), 1);
        nums.insert(nums.end(), 1);
    
        // rangeValues[i][j] is the maximum # of coins that can be obtained
        // by popping balloons only in the range [i,j]
        vector<vector<int>> rangeValues(nums.size(), vector<int>(nums.size(), 0));
        
        // build up from shorter ranges to longer ranges
        for (int len = 1; len <= N; ++len) {
            for (int start = 1; start <= N - len + 1; ++start) {
                int end = start + len - 1;
                // calculate the max # of coins that can be obtained by
                // popping balloons only in the range [start,end].
                // consider all possible choices of final balloon to pop
                int bestCoins = 0;
                for (int final = start; final <= end; ++final) {
                    int coins = rangeValues[start][final-1] + rangeValues[final+1][end]; // coins from popping subranges
                    coins += nums[start-1] * nums[final] * nums[end+1]; // coins from final pop
                    if (coins > bestCoins) bestCoins = coins;
                }
                rangeValues[start][end] = bestCoins;
            }
        }
        return rangeValues[1][N];
    }
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值