zoukankan      html  css  js  c++  java
  • [LeetCode] 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:

    • You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
    • 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

    Example:

    Input: [3,1,5,8]
    Output: 167 
    Explanation: 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

    戳气球。

    有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

    现在要求你戳破所有的气球。如果你戳破气球 i ,就可以获得 nums[left] * nums[i] * nums[right] 个硬币。 这里的 left 和 right 代表和 i 相邻的两个气球的序号。注意当你戳破了气球 i 后,气球 left 和气球 right 就变成了相邻的气球。

    求所能获得硬币的最大数量。

    说明:

    你可以假设 nums[-1] = nums[n] = 1,但注意它们不是真实存在的所以并不能被戳破。
    0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/burst-balloons
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    思路是动态规划。我先直接给出动态规划的方程和代码,至于怎么来的,之后我再补充。这是一道带有重叠子问题的动态规划题目,需要一个二维的动态规划数组 dp[i][j] 表示从第 i 个气球到第 j 个气球戳破所有气球能得到的最大分数。最后题目要求输出的是 dp[0][nums.length - 1] 。因为需要计算戳破第一个和最后一个气球的dp值,所以需要创建一个更长的数组来记录这个结果,并且这个更长的数组的第一个位置和最后一个位置上的值暂且定义为0。

    时间O(n^3)

    空间O(n^2)

    Java实现

     1 class Solution {
     2     int maxCoins(int[] nums) {
     3         int n = nums.length;
     4         // 添加两侧的虚拟气球
     5         int[] points = new int[n + 2];
     6         points[0] = points[n + 1] = 1;
     7         for (int i = 1; i <= n; i++) {
     8             points[i] = nums[i - 1];
     9         }
    10         // base case 已经都被初始化为 0
    11         int[][] dp = new int[n + 2][n + 2];
    12         // 开始状态转移
    13         // i 应该从下往上
    14         for (int i = n; i >= 0; i--) {
    15             // j 应该从左往右
    16             for (int j = i + 1; j < n + 2; j++) {
    17                 // 最后戳破的气球是哪个?
    18                 for (int k = i + 1; k < j; k++) {
    19                     // 择优做选择
    20                     dp[i][j] = Math.max(dp[i][j], dp[i][k] + dp[k][j] + points[i] * points[j] * points[k]);
    21                 }
    22             }
    23         }
    24         return dp[0][n + 1];
    25     }
    26 }

    LeetCode 题目总结

  • 相关阅读:
    《Linux命令行与shell脚本编程大全 第3版》Linux命令行---37
    《Linux命令行与shell脚本编程大全 第3版》Linux命令行---36
    《Linux命令行与shell脚本编程大全 第3版》Linux命令行---35
    《Linux命令行与shell脚本编程大全 第3版》Linux命令行---34
    《Linux命令行与shell脚本编程大全 第3版》Linux命令行---33
    scrollBarStyle- listview滑动条调整
    mk-编译信息的意义
    values-dimen 不同分辨率资源实现引用
    ubuntu-虚拟机分辨率设定
    vmware-虚拟机播放器的下载、安装
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13339457.html
Copyright © 2011-2022 走看看