LeetCode312、戳气球(难)

题目描述

https://leetcode-cn.com/problems/burst-balloons/
在这里插入图片描述

解法(动规)

看了大概7、8分钟,没有思路。自己暴力的想法是n的阶乘级别,代码也难写。直接看题解,很巧妙,很惊叹。

参考讲解:经典动态规划:戳气球
直接上代码:

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

        //定义两个虚拟气球,拓展了nums的长度,防止了下标越界的处理麻烦
        int [] new_nums = new int[nums.length+2];
        new_nums[0] = new_nums[new_nums.length-1] = 1;
        for(int i=1;i<=nums.length;i++){
            new_nums[i] = nums[i-1];
        }

        //dp[i][j]表示搓破(i,j)之间的气球获得的最大硬币数量

        //边界条件:dp[i][i] = 0,它们之间没有气球,dp[i][i= +1]=0;它们之间也没有气球
        int[][]dp = new int[new_nums.length][new_nums.length];

        //递推方程:找到可能最后搓破的k气球,使得得到的dp[i][j]为最大值
        //dp[i][j] = dp[i][k] + dp[k][j]+ point[i]*point[k]*point[j]
        //因为搓破了最后一个气球k则其相邻的气球为i和j。
        //戳破k之前必须先戳破dp[i][k]和dp[k][j]

        //确认遍历i和j的顺序,通过最终结果的位置和base case的位置以及要计算的递推方程确定。

        //斜着遍历,或者i从大到小,j从小到大,

        for(int i=nums.length;i>=0;i--){
            for(int j=i+1;j<new_nums.length;j++){
                for(int k=i+1;k<j;k++){//做选择
                    dp[i][j] = Math.max(dp[i][j],
                        dp[i][k] + dp[k][j]+ new_nums[i]*new_nums[k]*new_nums[j]);
                }
            }
        }
        return dp[0][nums.length+1];


    }
}

时间复杂度应该为O(n3)
在这里插入图片描述

感悟:区间dp就是缩小搜索范围的一个过程。
模板总结参考:https://leetcode-cn.com/problems/burst-balloons/solution/yi-wen-tuan-mie-qu-jian-dp-by-bnrzzvnepe-2k7b/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨夜※繁华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值