zoukankan      html  css  js  c++  java
  • leetcode 312.戳气球

    题目:

    有 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

    分析:

    我是看了别人的代码才懂的,这段代码是别人的,我自己后来写了一份,这里就贴上别人的代码,是在评论区里的。

    首先他的代码中已经给出了一定的解释,先去看一下然后再看我的解释。

    有一些朋友可能会不懂这个动态方程为什么这么写,假如现在有一行气球,我们定义最后戳破第k个气球可以得到最大的收益,首先我们要明白他注释中的 i 和 j 位置不一定是气球!也有可能是边界,也就是最后剩下的不是3个气球,而是一个气球,只是他的左右两边已经事先填充了两个不会被戳破的“气球”了。

    最后我们就可以得到了这个动态转移方程,每当加进来一个气球,我们就计算戳破第k个气球可以得到的收益,并且循环计算出最大的收益。当把最后一个气球给放入的时候,我们用原先计算的最大值就可以推导出最后的最大收益了。

     1 class Solution {
     2     public int maxCoins(int[] nums) {
     3         int[] balls = new int[nums.length+2];
     4         balls[0] = 1;
     5         balls[balls.length - 1] = 1;
     6         int[][] coins = new int[balls.length][balls.length];
     7         for(int i = 0; i < nums.length; i++)
     8         {
     9             balls[i+1] = nums[i];
    10         }
    11         
    12         for(int j = 2; j < balls.length; j++)
    13         {
    14             for(int i = j - 2; i >= 0; i--)
    15             {
    16                 for(int k = j -1; k > i; k--)
    17                 {
    18                     /* 这个里面的coins[i][k]  + balls[i]*balls[k]*balls[j] + coins[k][j]
    19                         是最大的可以这样理解:以k分割(为什么会有k,因为无论怎么戳,最后剩三个
    20                         的时候,一定是i,j和另一个,另一个就是k,那么要总的结果最大,那么要k
    21                         两边的值都取最
    22                         大,两边值最大是什么:即coins[i][k],coins[k][j],先戳两边的把两个最
    23                         大找出来,最后左右两边剩什么呢,正是最左边的balls[i]和最右边的balls[j],
    24                         最后处理k处的即balls[i]*balls[k]*balls[j]
    25                     */
    26                     coins[i][j] = Math.max(coins[i][j], coins[i][k]
    27                                           + balls[i]*balls[k]*balls[j] + coins[k][j]);
    28                 }
    29             }
    30         }
    31         for(int n=0;n<balls.length;++n) {
    32             System.out.println();
    33             for(int m=0;m<balls.length;++m)
    34                 System.out.print(coins[n][m]+" ");
    35         }
    36         return coins[0][balls.length - 1];
    37     }
    38 }
  • 相关阅读:
    [LeetCode] Contains Duplicate II
    [LeetCode] House Robber II
    [LeetCode] Permutations II
    [LeetCode] Permutations
    [LeetCode] Next Permutation
    谈谈套接字
    基于Linux系统的Nagios网络管理模块的实现
    Windows/Linux下磁盘使用的图形化工具简介
    利用日志使管理Linux更轻松
    实际感受美丽的Linux(多组视频)
  • 原文地址:https://www.cnblogs.com/CHAHA123/p/10692897.html
Copyright © 2011-2022 走看看