Leetcode 312. Burst Balloons

来源:互联网 发布:网络摄像头的安装步骤 编辑:程序博客网 时间:2024/06/06 04:28

问题描述

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.

Note:
(1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
(2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

Example:

Given [3, 1, 5, 8]

Return 167

    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

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

问题分析:
问题描述的是一个扎气球的过程,动态规划需要将过程划分阶段,确定状态以及状态转移方程。阶段即一个一个扎气球的过程,状态即从n个气球到n-1个气球的状态变化,但是这个的状态定义无法精确描述哪个阶段所扎的是哪个气球。另一方面,如果知道了哪个阶段扎的是哪个气球,状态转移方程没有办法清晰表示。
参考了网络上面大神的思路,真的好聪明
dp[l][r]表示扎破(l,r)范围内所有气球获得的最大硬币数,不含边界。
以最后被爆破的气球m为边界,把数组分为左右两个子区域,状态转移方程:
dp[l][r]=max(dp[l][r],nums[l]*nums[m]*nums[r]+dp[l][m]+dp[m][r]);
(这样通过回溯就可以把最优过程表示出来,状态以及状态转换方程都可以很容易的写出来,膜拜)
具体过程三成循环:
l与r的间隔k从2开始逐渐增大,
枚举左边界l
枚举中点m
参考代码:

    public int maxCoins(int[] Nums) {        int n=Nums.length+2;        int[]nums=new int[n];        nums[0]=nums[n-1]=1;        for(int i=1;i<n-1;i++)nums[i]=Nums[i-1];        int[][]dp=new int[n][n];        for(int k=2;k<n;k++){            for(int l=0;l<n-k;l++){                int r=l+k;                for(int m=l+1;m<r;m++){                    dp[l][r]=Math.max(dp[l][r],nums[l]*nums[m]*nums[r]+dp[l][m]+dp[m][r]);                }            }        }        return dp[0][n-1];    }

参考链接:
http://bookshadow.com/weblog/2015/11/30/leetcode-burst-balloons/
https://discuss.leetcode.com/topic/30746/share-some-analysis-and-explanations

原创粉丝点击