312. Burst Balloons

来源:互联网 发布:淘宝店铺关注怎么刷 编辑:程序博客网 时间:2024/06/08 12:03

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

题解:

这个题用divid and conquer的思想,但是如果按顺序走,弄破第一个气球Ai,Ai-1 和Ai+1会变成邻接的两个气球,没有办法分成两个部分。可以反过来进行思考,假如弄破的Ai是最后一个气球呢?那Ai-1 和Ai+1在Ai破之前已经破了,它们不会变成邻接的气球,于是就可以顺利把序列分成两个子序列进行计算了。和其他使用divid and conquer思想的题目一样,我们用memoization的方法记录子问题计算结果,避免重复计算。


代码:

public class Solution {    public int maxCoins(int[] nums) {        int[] temp = new int[nums.length+2];        int n = 1;        temp[0] = 1;        temp[nums.length + 1] = 1;        for(int i = 0; i < nums.length; i++) {            temp[n++] = nums[i];        }        n++;        int[][] dp = new int[n][n];        return helper(temp, dp, 0, n-1);            }        private int helper(int[] temp, int[][] dp, int left, int right) {        if(left + 1 == right) {            return 0;        }        if(dp[left][right] > 0) {            return dp[left][right];        }        int ans = 0;        for(int i = left + 1; i < right; i++) {            ans = Math.max(ans, temp[left]*temp[i]*temp[right] + helper(temp, dp, left, i) + helper(temp,dp,i,right));        }        dp[left][right] = ans;        return ans;    }}




0 0
原创粉丝点击