[LeetCode]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

这道题的题意是:给出从0到n-1共n个热气球,每一个热气球都标记有一个数字,数字存储在nums数组中,我们需要戳爆一个热气球i,得到nums[left] * nums[i] * nums[right],其中left和right表示i相邻的两个标号,如果戳爆了i,left和right会相邻。

这道题的难度还是比较大的,不太容易想到好的做法,我尝试了多种方式后,没能解决这个问题,查阅了很多博客之后才了解了这道题的解法。这是一道动态规划的题,我们用dp[l][r]表示戳爆left和right之间所有的热气球得到的值,注意这里并不包括边界left和right。另k = l - r,表示从左到右的跨度,我们最终只需要返回k = nums.size() - 1时,也就是dp[0][nums.size() - 1]的值即可。

dp[l][r]的计算方法则是遍历l和r之间所有i,取nums[l] * nums[i] * nums[r]的最大值即可。

我们在nums的开头和结尾添加一个1来定义边界,然后从2到nums.size()遍历k,对每个k又遍历所有l和k,此时r = l + k, 计算dp[l][r]的值,遍历结束后,dp[0][nums.size() - 1]就是我们所要求的结果。


class Solution {
public:
    int maxCoins(vector<int>& nums) {
    	nums.insert(nums.begin(), 1);
    	nums.push_back(1);
    	vector<vector<int> > dp;
    	for(int i = 0; i < nums.size(); i++) {
    		vector<int> temp;
    		for (int j = 0; j < nums.size(); j++) {
    			temp.push_back(0);
			}
			dp.push_back(temp);
		} 
        for (int k = 2; k < nums.size(); k++) {
        	for (int l = 0; l < nums.size() - k; l++) {
        		int r = l + k;
        		for (int i = l + 1; i < r; i++) {
        			dp[l][r] = max(dp[l][r], dp[l][i] + nums[l] * nums[i] * nums[r] + dp[i][r]);
				}
			}
		}
		return dp[0][nums.size()-1];
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值