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 题目汇总

  • 相关阅读:
    看懂SqlServer查询计划
    Android开发16——获取网络资源之基础应用
    Android开发15——给TextView加上滚动条
    PeekMessage、GetMessage的区别
    获取不到Repeater控件中的CheckBox选中状态
    第十九讲:动态链接库
    孙鑫VC++视频教程笔记
    CEdit 控制键盘操作
    网络编程中粘包的处理方法
    VC++编程之道读书笔记(2)
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8628221.html
Copyright © 2011-2022 走看看