0312. Burst Balloons (H)

Burst Balloons (H)

題目

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.java

Find the maximum coins you can collect by bursting the balloons wisely.code

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

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

題意

打氣球遊戲。每一個氣球有對應的分值,打爆一個氣球i,能獲得的積分爲氣球i、氣球i-一、氣球i+1積分的乘積。要求計算可以得到的最大積分。it

思路

動態規劃問題。dp[left, right]表示打爆從left到right全部氣球能獲得的最大積分。每一次咱們在[left, right]這個區間中選擇一個i,表明該區間中最後一個被打爆的氣球,那麼能夠獲得遞推關係式:io

\[dp[left,\ right]=\max_{left \le i \le right}(dp[left,\ i-1]+dp[i+1,\ right]+nums[left-1]*nums[i]*nums[right+1]) \]


代碼實現

Java

記憶化搜索

class Solution {
    public int maxCoins(int[] nums) {
        int[][] memo = new int[nums.length][nums.length];
        for (int i = 0; i < nums.length; i++) {
            Arrays.fill(memo[i], -1);
        }
        return dfs(nums, 0, nums.length - 1, memo);
    }

    private int dfs(int[] nums, int left, int right, int[][] memo) {
        if (right < left) {
            return 0;
        }
        if (memo[left][right] != -1) {
            return memo[left][right];
        }
        int max = 0;
        for (int i = left; i <= right; i++) {
            int x = dfs(nums, left, i - 1, memo)
                    + dfs(nums, i + 1, right, memo)
                    + nums[i] * (left == 0 ? 1 : nums[left - 1]) * (right == nums.length - 1 ? 1 : nums[right + 1]);
            max = Math.max(max, x);
        }
        memo[left][right] = max;
        return max;
    }
}

動態規劃

class Solution {
    public int maxCoins(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }

        int[][] dp = new int[nums.length][nums.length];
        for (int right = 0; right < nums.length; right++) {
            for (int left = right; left >= 0; left--) {
                for (int i = left; i <= right; i++) {
                    int leftMax = i == left ? 0 : dp[left][i - 1];
                    int rightMax = i == right ? 0 : dp[i + 1][right];
                    int last = nums[i] * (left == 0 ? 1 : nums[left - 1]) * (right == nums.length - 1 ? 1 : nums[right + 1]);
                    dp[left][right] = Math.max(dp[left][right], leftMax + rightMax + last);
                }
            }
        }
        return dp[0][nums.length - 1];
    }
}
相關文章
相關標籤/搜索