312. 戳气球

有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1 和 i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1或 i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。

求所能获得硬币的最大数量。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/burst-balloons
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

区间[i, j]最后戳气球,枚举每个最后戳气球的位置

记忆化搜索

import java.util.Arrays;

class Solution {

    private int[] nums;

    private int[][] dp;

    private int value(int index) {
        if (index == -1 || index == nums.length) {
            return 1;
        }
        return nums[index];
    }

    private int solve(int left, int right) {
        if (left > right) {
            return 0;
        }
        if (dp[left][right] != -1) {
            return dp[left][right];
        }

        int ans = Integer.MIN_VALUE;
        for (int i = left; i <= right; ++i) {
            ans = Math.max(ans, value(left - 1) * value(i) * value(right + 1) + solve(left, i - 1) + solve(i + 1, right));
        }

        dp[left][right] = ans;

        return dp[left][right];
    }

    public int maxCoins(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        this.nums = nums;
        this.dp = new int[nums.length][nums.length];
        for (int i = 0; i < nums.length; ++i) {
            Arrays.fill(dp[i], -1);
        }
        return solve(0, nums.length - 1);
    }
}

动态规划

class Solution {


    private int[] nums;

    private int value(int index) {
        if (index == -1 || index == nums.length) {
            return 1;
        }
        return nums[index];
    }

    private int dp() {
        int n = nums.length;
        int[][] dp = new int[n][n];


        for (int left = n - 1; left >= 0; --left) {
            dp[left][left] = value(left - 1) * value(left) * value(left + 1);
            for (int right = left + 1; right < n; ++right) {
                dp[left][right] = Math.max(dp[left + 1][right] + value(left - 1) * value(left) * value(right + 1),
                        dp[left][right - 1] + value(left - 1) * value(right) * value(right + 1));
                for (int first = left + 1; first < right; ++first) {
                    dp[left][right] = Math.max(dp[left][right], dp[left][first - 1] + dp[first + 1][right] + value(left - 1) * value(first) * value(right + 1));
                }
            }
        }

        return dp[0][n - 1];
    }

    public int maxCoins(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        this.nums = nums;
        return dp();
    }
}

使用辅助数组

class Solution {

    private int[][] dp;

    private int solve(int[] helper, int left, int right) {
        if (right - left <= 1) {
            return 0;
        }
        if (dp[left][right] != -1) {
            return dp[left][right];
        }
        int ans = Integer.MIN_VALUE;
        for (int i = left + 1; i < right; i++) {
            ans = Math.max(ans, helper[i] * helper[left] * helper[right] + solve(helper, left, i) + solve(helper, i, right));
        }
        dp[left][right] = ans;
        return ans;
    }

    private int solve(int[] helper) {
        int[][] dp = new int[helper.length][helper.length];
        for (int left = helper.length - 3; left >= 0; left--) {
            for (int right = left + 2; right < helper.length; right++) {
                for (int k = left + 1; k < right; k++) {
                    dp[left][right] = Math.max(dp[left][right], helper[k] * helper[left] * helper[right] + dp[left][k] + dp[k][right]);
                }
            }
        }
        return dp[0][helper.length - 1];
    }

    public int maxCoins(int[] nums) {
        int[] helper = new int[nums.length + 2];
        helper[0] = helper[helper.length - 1] = 1;
        for (int i = 1; i <= nums.length; i++) {
            helper[i] = nums[i - 1];
        }
//        dp = new int[helper.length][helper.length];
//        for (int[] d : dp) {
//            Arrays.fill(d, -1);
//        }
//        return solve(helper, 0, helper.length - 1);
        return solve(helper);
    }
}
posted @ 2021-12-28 10:30  Tianyiya  阅读(69)  评论(0)    收藏  举报