Burst Balloons

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.

Example

Example 1:

Input:[4, 1, 5, 10]
Output:270
Explanation:
nums = [4, 1, 5, 10] burst 1, get coins 4 * 1 * 5 = 20
nums = [4, 5, 10]   burst 5, get coins 4 * 5 * 10 = 200 
nums = [4, 10]    burst 4, get coins 1 * 4 * 10 = 40
nums = [10]    burst 10, get coins 1 * 10 * 1 = 10
Total coins 20 + 200 + 40 + 10 = 270

Example 2:

Input:[3,1,5]
Output:35
Explanation:
nums = [3, 1, 5] burst 1, get coins 3 * 1 * 5 = 15
nums = [3, 5] burst 3, get coins 1 * 3 * 5 = 15
nums = [5] burst 5, get coins 1 * 5 * 1 = 5
Total coins 15 + 15 + 5  = 35

Notice

  • 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

思路:f[i][j]代表:i个气球和j个气球不能被扎破的情况下,中间扎破能够得到的最大值。
记住首尾先要加入一个1,然后区间型动态规划,一定是先计算小区间然后计算大区间,所以for循环用len来写,然后枚举起点,最后得到整个区间的最大值;O(N^3);

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

思路2:这题可以用Stone Game的记忆化递归来做,score(start, end, fullNums, cache); O(N^3); top down的解法;也就是算每个一点,最后扎破,看计算出来谁最大,谁就是答案;扎破中间的气球的时候,假设左右两边全部爆掉了;也就是看最后一步;O(N^3);

class Solution {
    public int maxCoins(int[] nums) {
        int n = nums.length;
        int[] A = new int[n + 2];
        A[0] = A[n + 1] = 1;
        for(int i = 1; i <= n; i++) {
            A[i] = nums[i - 1];
        }
        n = n + 2;
        int [][] cache = new int[n][n];
        return dfs(A, 0, n - 1, cache);
    }
    
    private int dfs(int[] A, int start, int end, int[][] cache) {
        if(start >= end) {
            return 0;
        }
        if(cache[start][end] != 0) {
            return cache[start][end];
        }
        for(int k = start + 1;  k < end; k++) {
            cache[start][end] = Math.max(cache[start][end], A[start] * A[k] * A[end] 
                               + dfs(A, start, k, cache) + dfs(A, k, end, cache));
        }
        return cache[start][end];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值