LeetCode 312. Burst Balloons--动态规划

来源:互联网 发布:大数据可视化 网络攻击 编辑:程序博客网 时间:2024/06/05 00:45

题目链接

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];    }};