zoukankan      html  css  js  c++  java
  • [LeetCode] 312. 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.

    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个气球,每个气球都对应一个数字,每次打爆一个气球,得到的金币数是被打爆的气球的数字和其两边的气球上的数字相乘,如果旁边没有气球了,则按1算,求能得到的最多金币数。

    解法:动态规划DP,

    State: dp[i][j],表示打爆区间[i,j]中的所有气球能得到的最多金币。题目中说明了边界情况,当气球周围没有气球的时候,旁边的数字按1算,这样我们可以在原数组两边各填充一个1,这样方便于计算。

    Function: dp[i][j] = max(dp[i][j], nums[i - 1]*nums[k]*nums[j + 1] + dp[i][k - 1] + dp[k + 1][j]) ( i ≤ k ≤ j )

    Return: dp[1][n]中,其中n是两端添加1之前数组nums的个数。

    Java:

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

    Python:

    class Solution(object):
        def maxCoins(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            coins = [1] + [i for i in nums if i > 0] + [1]
            n = len(coins)
            max_coins = [[0 for _ in xrange(n)] for _ in xrange(n)]
        
            for k in xrange(2, n):
                for left in xrange(n - k):
                    right = left + k
                    for i in xrange(left + 1, right):
                        max_coins[left][right] = max(max_coins[left][right], 
                               coins[left] * coins[i] * coins[right] + 
                               max_coins[left][i] + max_coins[i][right])
    
            return max_coins[0][-1]  

    C++:

    class Solution {
    public:
        int maxCoins(vector<int>& nums) {
            int n = nums.size();
            nums.insert(nums.begin(), 1);
            nums.push_back(1);
            vector<vector<int> > dp(nums.size(), vector<int>(nums.size() , 0));
            for (int len = 1; len <= n; ++len) {
                for (int left = 1; left <= n - len + 1; ++left) {
                    int right = left + len - 1;
                    for (int k = left; k <= right; ++k) {
                        dp[left][right] = max(dp[left][right], nums[left - 1] * nums[k] * nums[right + 1] + dp[left][k - 1] + dp[k + 1][right]);
                    }
                }
            }
            return dp[1][n];
        }
    };
    

      

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    java例程练习(多态/动态绑定/迟绑定)
    java例程练习(对象转型及instanceof关键字)
    java例程练习(对象类型数据的排序)
    java例程练习(数三退一[用数组模拟])
    SSL协议与数字证书原理
    SSL和数字证书服务慨述(3)
    数字证书介绍
    SSL和数字证书服务慨述(1)
    SSL和数字证书服务慨述(2)
    如何设置word页脚中的总页码
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8628221.html
Copyright © 2011-2022 走看看