LeetCode Week11: Burst Ballons

来源:互联网 发布:网络推广微商seocnm 编辑:程序博客网 时间:2024/05/22 18:18

本周完成的题目是关于动态规划的题目,这里选择Burst Ballons来写题解。

题目

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 

我的分析

这是一个动态规划的典型题目,具体的过程可以看作是对一个dp[nums.size()+2][nums.size()+2]数组的填充,其中nums.size()+2表示的是在原序列的头尾分别加入一个元素1。定义f[i][j]表示从i到j最多可以剪切然后得到的最大价值,定义l到r的长度为len,len最小为2,最大为序列长度。这样在序列中才会存在气球,
这里举例说明怎么用len来计算总体的奖励。
len = 2,”“表示当前(l,r)序列中包含的气球:

(0,2): f[0][2] = 1 “3” 1 5 8 1
=>消除”3” ans = max(f[0][2],1*3*1+rec[0][1]+rec[1][2]) = 3;
(1,3): f[1][3] = 1 3 “1” 5 8 1
=>消除”1” ans = max(f[1][3],3*1*5+rec[1][2]+rec[2][3]) = 15;
(2,4): f[2][4] = 1 3 1 “5” 8 1
=>消除”5” ans = max(f[2][4],1*5*8+rec[2][3]+rec[3][4]) = 40;
(3,5): f[3][5] = 1 3 1 5 “8” 1
=>消除”8” ans = max(f[3][5],5*8*1+rec[3][4]+rec[4][5]) = 40;

所以当len=2时,我们考虑的是原序列中的单个元素被去除时的价值
len = 3:

f[0][3] = 1 “3” “1” 5 8 1
=>先消除”3” ans = max(f[0][3],1*3*5+rec[0][1]+rec[1][3]) = 30;
=>先消除”1” ans = max(f[0][3],1*1*5+rec[0][2]+rec[2][3]) = max(30,8) = 30;
f[1][4] = 1 3 “1” “5” 8 1
=>先消除”1” ans = max(f[1][4],3*1*8+rec[1][2]+rec[2][4]) = 64;
=>先消除”5” ans = max(f[1][4],3*5*8+rec[1][3]+rec[3][4]) = max(64,135) = 135;
.
.
.

即,每次定义一个len长度,这个长度是区间(l,r)的长度,f(l,r)表示的是从l开始到r的气球序列中捏爆气球的奖励。这样的话,随着len的不断变大,我们就可以得到对于所有序列捏爆气球的最大奖励:
f[l][r]=max(f[l][r],nums[l]nums[i]nums[r]+f[l][i]+f[i][r])
因为我们会对不同的区间进行判断,所以这实际是一个上三角矩阵的填充过程,最开始填充的是第一行第三列开始的对角线,因为f[0][2]表示的是从位置0到位置2的气球被捏爆的奖励, 只有起始位置大于等于2,才有可能包括至少一个气球。
对于给定例子,最终的矩阵填充过程及值为:
这里写图片描述

代码

class Solution {public:    int maxCoins(vector<int>& nums) {        nums.push_back(1);        nums.insert(nums.begin(),1);        int rec[100][100] = {0};        for(int len = 2; len < nums.size(); len++)            for(int l = 0; l < nums.size()-len;l++){                int r = l+len;                for(int i = l+1; i < r;i++)                    rec[l][r] = max(rec[l][r],rec[l][i]+rec[i][r]+nums[l]*nums[i]*nums[r]);            }        return rec[0][nums.size()-1];    }};
0 0
原创粉丝点击