zoukankan      html  css  js  c++  java
  • 动态规划-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 };
    复制代码
  • 相关阅读:
    Apollo的Oracle适配改动
    尝试Java,从入门到Kotlin(下)
    尝试Java,从入门到Kotlin(上)
    RabbitMQ权限控制原理
    一文彻底掌握二叉查找树(多组动图)(史上最全总结)
    图解:深度优先搜索与广度优先搜索及其六大应用
    图解:如何理解与实现散列表
    图解:什么是“图”?
    查找算法系列文(一)一文入门二叉树
    线性表(数组、链表、队列、栈)详细总结
  • 原文地址:https://www.cnblogs.com/huenchao/p/5956561.html
Copyright © 2011-2022 走看看