312. Burst Balloons

来源:互联网 发布:行政审批流程优化方案 编辑:程序博客网 时间:2024/04/29 07:10

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];}};


0 0
原创粉丝点击