LeetCode 312. Burst Balloons--动态规划

题目链接

312. Burst Balloons

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

解:

真的是很难想的一题,参考了在线疯狂的博客的思路:

(看到这个思路时我发现我一直想不出是因为我没有仔细考虑  “(1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.  这句话)

1.子问题的解是父问题解的一部分,满足这个条件,符合动态规划的要求

2.注意到“求数组得到的最大值在最前和最后分别加一个1,1不能爆”,用dp[i][j]代表子序列(i,j)产生的最大值,不包括 i 和 j ,value[]表示每一位置的数值,value的大小是nums大小(size)加2,首位分别都是1,我们最后想得到的结果就可以用dp[0][size+1]表示

3.dp[i,j] = max(dp[i,last]+dp[last,j]+value[last]*value[i]*value[j]),i < last < j ,last的含义是在i和j之间最后爆的气球,last可以将一个序列分隔为2部分,序列的最大值就是2个子序列的最大值加上last爆时产生的值

代码(c++):

class Solution {
public:
    int maxCoins(vector<int>& nums) {
        int size = nums.size();
        int dp[502][502] = {0};
        int value[502];
        value[0] = 1;
        for (int i = 1; i <= size; i++) value[i] = nums[i-1];
        value[size+1] = 1;
        for (int i = 0; i < size-1; i++) dp[i][i+1] = 0;
        for (int len = 2; len < size+2; len++) {
            for (int i = 0; i < size; i++) {
                int j = i+len;
                for (int last = i+1; last <= j-1; last++) {
                    dp[i][j] = max(dp[i][j], dp[i][last] + dp[last][j] + value[last]*value[i]*value[j]);
                }
            }
        }
        return dp[0][size+1];
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值