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


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





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值