• 动态规划-Burst Balloons


    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

    https://leetcode.com/problems/burst-balloons/


    分治+动态规划。

    https://leetcode.com/discuss/72216/share-some-analysis-and-explanations

    先是暴力的思路,n个气球一个个踩,剩下n - 1个再按顺序踩,一直到最后,复杂度爆表TLE。

    加入分治的思想,踩了一个气球后,数组就分成左右两部分,但问题是左边和右边不是独立的,这样分治结果是错的。

    逆向思考,最后只有一个气球的时候,结果的是肯定的,因为这个气球的左右分别是左边界和右边界。

    举例来说,数组[A,B,C,D,E,F,G],代表任意数字。

    首先去掉所有的零,在头和尾加上两个1表示边界。

    最外层循环就是从A到G,代表了最后一个踩的气球。

    假设遍历到C这个点,最后要踩C,那么C的值是固定的,为1 * C * 1。

    然后考虑两边,左边的是以1和C为边界,求出最大值,右边是以C和1为边界求最大值,如图所示。

    递归求出结果。

    还要开一个二维数组记录中间结果提高效率。

    复制代码
     1 /**
     2  * @param {number[]} nums
     3  * @return {number}
     4  */
     5 var maxCoins = function(nums) {
     6     var dp = [], i, numArr = [1];
     7     for(i = 0; i <nums.length; i++){
     8         if(nums[i] !== 0) numArr.push(nums[i]);
     9     }
    10     numArr.push(1);
    11     var len = numArr.length;
    12     for(i = 0; i < len; i++){
    13         dp[i] = [];
    14     }
    15     return burstBalloons(1, len - 2);
    16 
    17     function burstBalloons(start, end){
    18         if(start > end) return 0;
    19         if(dp[start][end]) return dp[start][end];
    20         var max = -Infinity;
    21         for(var i = start; i <= end; i++){
    22             max = Math.max(max, numArr[start - 1] * numArr[i] * numArr[end + 1] +
    23                 burstBalloons(start, i - 1) + burstBalloons(i + 1, end));            
    24         }
    25         dp[start][end] = max;
    26         return max;
    27     }
    28 };
    复制代码
  • 相关阅读:
    【luogu】P1772物流运输(最短路+DP)
    【Bzoj】1001狼抓兔子(平面图最小割转对偶图最短路)
    后记
    【Luogu】P2680运输计划(树上差分+二分)
    【Luogu】P2059卡牌游戏(概率DP)
    【Luogu】P2051中国象棋(DP)
    概率与期望学习笔记
    【Luogu】P2894酒店Hotel(线段树)
    21.Mysql Server优化
    20.Mysql锁机制
  • 原文地址:https://www.cnblogs.com/huenchao/p/5956561.html
Copyright © 2020-2023  润新知