Burst Balloons

来源:互联网 发布:mac 退出less 编辑:程序博客网 时间:2024/05/21 14:06
Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by arraynums. You are asked to burst all the balloons. If the you burst ballooni you will get nums[left] * nums[i] * nums[right] coins. Hereleft and right are adjacent indices of i. After the burst, theleft 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


      一开始看到这个题目的时候,很明显的动态规划题,然后我最开始的想法是将所有球这个序列分成多个小的序列,用一个数组来存储在每一段中的最好值,而大的段可以利用小的段得到自己的最好值,也就是分治的想法,然后在解决一段的最好值的时候,首先想到的是先打一个球,但是明显,只要打掉某个球,剩下的球就会组成一个新的数列,有完全不一样的下一步可以走,这样显然不行,后来想到的是最后打某一个球,然后将这个球的左边先全部打掉,右边也全部打掉,而且左边与右边互不影响,因为有当前选定球在中间将两段隔开,然后最后当前选定球被打掉的时候,其左右两边的球就是边界上的球,这也是可以定的,于是可以对每一段进行遍历,得到每一段中最后打掉哪个球失最好的值,也就是这一段中最好的值,然后再利用分治的想法,对其进行递归,就可以得到整个序列的最好的值了。这个算法最难的还是理解做法,这里利用了分治与动态规划的思想来解决这道题目,算法复杂度由于是在递归的循环中,利用了两次递归,但是利用计算过的值减少重复的计算所以小于N!,具体的复杂度。。不怎么好计算,但应该在N^3左右。。


解决代码如下:

class Solution {public:    int maxCoins(vector<int>& nums) {int n=nums.size();        vector<vector<int> > coin(n+2, vector<int>(n+2, 0));        nums.insert(nums.begin(), 1);    nums.insert(nums.end(), 1);    return max(0, n+1, nums, coin);            }        int max(int begin, int end, vector<int> &nums, vector<vector<int> >& coin)    {        if(begin+1==end)        return 0;    if(coin[begin][end] != 0)    return coin[begin][end];        for(int i=begin+1; i<end; i++)    {    int temp = max(begin, i, nums, coin) + nums[i]*nums[begin]*nums[end] + max(i, end, nums, coin);    if(temp > coin[begin][end]) coin[begin][end] = temp;    }    return coin[begin][end];    }};





0 0
原创粉丝点击