LeetCode | Burst Balloons

Problem
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
(1) nums[-1] = nums[n] = 1
(2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

Example

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

Solution
DP问题,和之前的模式不太一样。按照之前的思路,考虑第一个把第i个气球爆掉,序列变成两部分。但是每部分的首/尾值和另一部分相关联,且会随另一部分爆气球的不同顺序变化,不可取。

换个思路,考虑第i个气球是最后一个被爆掉的,序列也可以分为两部分,且只与第i个气球关联。因为i在被爆掉前都是固定的,所以就得到了相同条件的子问题。另外,零值气球对结果没有影响可以直接去掉。

取状态dp[i][j]为第i+1到j-1个气球被爆掉后得到的最大金币数,每次都考虑最后一个被爆掉的气球i,状态转移为dp[left][right] = max(dp[left][right], nums[left]*nums[i]*nums[right] + dp[left][i] + dp[i][right]).


int maxCoins(vector<int>& nums) {

    vector<int> coins;
    coins.push_back(1);
    for (int i = 0; i < nums.size(); ++i) 
        if (nums[i] > 0)
            coins.push_back(nums[i]);
    coins.push_back(1);

    int dp[coins.size()][coins.size()] = {};
    for (int length = 2; length < coins.size(); ++length) {
        for (int left = 0; left < coins.size()-length; ++left) {
            int right = left + length;
            for (int mid = left+1; mid < right; ++mid) {
                dp[left][right] = max(dp[left][right], 
                    coins[left]*coins[mid]*coins[right] + 
                    dp[left][mid] + dp[mid][right]);
            }
        }
    }
    return dp[0][coins.size()-1];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值