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 }

 

posted @ 2019-04-11 21:57  你说你好  阅读(373)  评论(0编辑  收藏  举报