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

输入一个数组nums,数组中的每一个数字代表一个气球,当选择戳破第i个气球的时候,就能获得 nums[i - 1] * nums[i] * nums[i + 1] 个金币,然后i - 1和i + 1就会成为相邻气球。问你能获得的最大金币数是多少(设nums[-1]和nums[n]均为1,但是是不可以戳破的)。

这道题可以利用动态规划来解决,首先我们要确定如何将大问题转化成小问题,设maxC[left][right]表示戳破(left, right)开区间内所有气球能获得的最大金币数,mid表示为在该区间内最后一个戳破的气球,那么就可以将问题转化为两个小问题:计算maxC[left][mid]和maxC[mid][right],当然mid可能是left和right之间的任何一个气球,因此得出状态转移方程为:

maxC[left][right] = max(maxC[left][mid] + maxC[mid][right] + nums[left] * nums[mid] * nums[right]), 其中 left<mid<right

代码如下(时间复杂度是,即O(n^3)):


class Solution {
public:
	int maxCoins(vector<int>& nums) {
		int n = nums.size() + 2;
		nums.insert(nums.begin(), 1);
		nums.push_back(1);
		vector<vector<int>> maxC(n, vector<int>(n, 0));
		for (int k = 2; k < n; k++) {                   // k为步长
			for (int left = 0; left < n - k; left++) {
				int right = left + k;
				for (int mid = left + 1; mid < right; mid++)
					maxC[left][right] = max(maxC[left][right], maxC[left][mid] +
						nums[left] * nums[mid] * nums[right] + maxC[mid][right]);
			}
		}
		return maxC[0][n - 1];
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值