Leetcode 312. Burst Balloons

博客围绕气球爆破问题展开,给定气球序列,打破气球i得分是气球i - 1、i、i + 1的值相乘,求打破顺序使总分最大。将其视为DP问题,通过局部解推全局解,还给出动态规划表示例,代码上在序列前后加值为1的气球方便处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

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 you burst balloon 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个气球的序列,每个气球具有不同的值,有如下规则,假设打破气球i,那么得到的值为气球i-1乘上气球i乘上气球i+1,之后气球i移出序列,题目需要求的是,打破的顺序要如何处理才能是得分总数最大。

 

 

解法:

这题可以看成是一个DP问题,我们可以由一小部分的解推到全局解。

举个例子 

假设我们求 2到4气球的打破的最大值,那么我们只需要确定最后打破哪个即可

如果最后打破4号,那么这个数值会为 max(num[1~3])+ num[-1]*num[4]*num[5]  (假设打破1到3的数值在之前已求出)

 如果最后打屁 3号 那么数值为  max(num[1~2])+max(num[4])+num[-1]*num[3]*num[5]

如果最后打破 2 。。。。。。。

 

依据这个思路,我们可以做一张动态规划的表dp[][]     我们使用dp[i][j] 来表示打破i到j之间的气球所能达到的最大值

对于 3 1 5 8 这个气球序列 我们可以得到下表(括号里为填表的顺序)

 

 

代码实现:

代码方面,为了方便处理 我们在气球序列的前后各加了一个数值为1的气球,方便计算题中所说的边界 num【-1】 num【n】为1

class Solution {
    public int maxCoins(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int array[] = new int[nums.length + 2];
        array[0] = 1;
        array[array.length-1] = 1;
        for (int i = 0; i < nums.length; i++) {
            array[i+1] = nums[i];
        }
        int[][] dp = new int[array.length][array.length];
        for(int i=1;i<array.length-1;i++){
            for(int j=i;j>=1;j--){
                 for (int k=j; k <= i; k++) {
                      dp[j][i] = Math.max(array[j-1]*array[k]*array[i+1] + dp[j][k-1] + dp[k+1][i], dp[j][i]);
            }
            }
        }
        return dp[1][array.length-2];
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值