[LeetCode] Burst Balloons

public class Solution {
    // 从最后一个burst的入手,dp[i][j]为i与j之间所有均已经burst的话所得分数的max
    public int maxCoins(int[] iNums) {
        int[] nums = new int[iNums.length + 2];
        int n = 1;
        // 将其中为0的剪枝
        for(int x : iNums){
            if (x > 0) nums[n++] = x;
        }
        // 先赋值,后自增,如果是nums[++n]的话就是先自增,后赋值
        nums[0] = nums[n++] = 1;
        int[][] dp = new int[n][n];
        // k是left与right之间的距离
        for (int k = 2; k < n;k++){
            for (int left = 0; left < n - k; left++) {
                int right = left + k;
                for (int i = left + 1; i < right; i++) {
                    dp[left][right] = Math.max(dp[left][right], nums[left] * nums[i] * nums[right] + dp[left][i] + dp[i][right]);
                }
            }
        }
        return dp[0][n-1];        
    }
}

本题是一道非常明显的DP问题,之所以没有思路,原因在于没有找到合适的DP矩阵来表示状态,由此得出一个教训,实现DP问题的时候一定要从bottom to top和top to bottom两种角度去考虑问题。本题即为reverse think,反向思考。


另:本题有两种解法,另一种解法如下:


public class Solution {
    public int maxCoins(int[] iNums) {
        int[] nums = new int[iNums.length + 2];
        int n = 1;
        for(int x : iNums){
            if (x > 0) nums[n++] = x;
        }
        nums[0] = nums[n++] = 1;
        int[][] dp = new int[n][n];
        return burst(dp, nums, 0, n - 1);
    }
    
    private int burst(int[][] dp, int[] nums, int left, int right) {
        if (left == right - 1) return 0;
        if (dp[left][right] > 0) return dp[left][right];
        int ans = 0;
        for (int i = left + 1; i < right; i++) {
            ans = Math.max(ans, nums[left] * nums[i] * nums[right] + burst(dp, nums, left, i) + burst(dp, nums, i, right));
        }
        dp[left][right] = ans;
        return ans;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值