n 个气球,编号为0n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

现在要求你戳破所有的气球。每当你戳破一个气球 i 时,你可以获得 nums[left] * nums[i] * nums[right] 个硬币。 这里的 leftright 代表和 i 相邻的两个气球的序号。注意当你戳破了气球 i 后,气球 left 和气球 right 就变成了相邻的气球。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

求所能获得硬币的最大数量。

说明:

  • 你可以假设 nums[-1] = nums[n] = 1,但注意它们不是真实存在的所以并不能被戳破。
  • 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

示例:

输入: [3,1,5,8]
输出: 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
class Solution {
    public int maxCoins(int[] nums) {
        if (nums.length == 0)
            return 0;
        else if (nums.length == 1)
            return nums[0];

        int[][] dp = new int[nums.length][nums.length];
        for (int i = 0; i < nums.length; i++)
            dp[i][i] = nums[i] * (i == 0 ? 1 : nums[i - 1]) * (i == nums.length - 1 ? 1 : nums[i + 1]);

        for (int i = nums.length - 1; i >= 0; i--) {
            for (int j = i; j < nums.length; j++) {
                int max = 0;
                for (int k = i; k <= j; k++) {
                    int score = nums[k] * (i == 0 ? 1 : nums[i - 1]) * (j == nums.length - 1 ? 1 : nums[j + 1])
                            + (k == i ? 0 : dp[i][k - 1]) + (k == j ? 0 : dp[k + 1][j]);
                    max = max > score ? max : score;
                }

                dp[i][j] = max;
            }
        }


        return dp[0][nums.length - 1];
    }

}
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄