【LeetCode】312. Burst Balloons爆破气球得到最大金币数

7 篇文章 0 订阅

问题描述

给定n个气球,每个气球对应一个编号,用数组nums[0…n-1]存放,打爆一个气球能够获得金币数:nums[left] * nums[i] * nums[right],然后这个数被移除,left和right变为相邻。求能够获得的最多的金币数量。
注:①假设nums[-1] = nums[n] = 1
② 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

例: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


这也是一道可用DP解答的问题。
这个气球将要获得的金币数跟已经爆掉的那些气球没关(数组中已经把爆掉的气球删除),因此子问题划分时,不是要知道第一个应该爆掉的气球,而是要知道最后一个爆掉的气球。

dp[l][r]:表示爆炸这些气球nums[l…r]的最大金币数。
上述例子中,为方便最末端的两个气球爆炸,我们分别再补两个“1”,nums=[1,3,1,5,8,1]。首先l+3≤r才有意义,所以我们可以设置一个变量len从3开始,循环到数组长度;然后l从0开始移动这个长为len的窗口;最后i指向这个窗口中最后一个爆炸的气球,从l+1开始遍历直到r-1。下图表示最后一个气球爆的8。
Mou icon

  1. 初始化:考虑边界情况,dp[0]=0

  2. 状态转移方程:注意要时刻更新dp[l][r]的值
    dp[l][r] = max( dp[l][r] , nums[l] * nums[i] * nums[r] + dp[l][i] + dp[i][r] )

  3. 返回值:dp[0][n-1]

class Solution {  
public:  
    int maxCoins(vector<int>& nums) {  
        nums.insert(nums.begin(), 1);  
        nums.push_back(1);  
        int n = nums.size();  

        vector<vector<int>> dp(n, vector<int>(n));  
        for(int len=3; len <= n; len++){  
            for(int l=0; l <= n-len; l++){  
                int r = l+len-1;  
                for(int i=l+1; i<r; i++){  
                    dp[l][r] = max(dp[l][r],(dp[l][i]+dp[i][r]+nums[l]*nums[i]*nums[r]));  
                }  
            }  
        }  
        return dp[0][n-1];  
    }  
}; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值