当前位置:   article > 正文

动态规划求解扎气球得金币游戏_刚刚今天去游乐场玩,发现了一个新的游戏项目,游戏是这样的,场上一共有 n 个气

刚刚今天去游乐场玩,发现了一个新的游戏项目,游戏是这样的,场上一共有 n 个气

1. 问题

  给定n个气球,编号从0至n-1,每个气球上写了一个数字,这些数字存放在数组nums中。现在你来扎破所有的气球。当扎破第i个气球时,可以得到的金币个数为nums[left] * nums[i] * nums[right],这里的left和right指的是第i个气球相邻气球的编号。(当扎破一个气球后,原来它左右侧的气球将成为相邻气球)。
  求通过扎气球可以获得的最大金币数量。

说明:

(1) 可以假想nums[-1] = nums[n] = 1,当然,它们仅仅是为了方便假想出来的,并不能够被扎破
(2) 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
  • 1
  • 2

2. 图解分析

这里写图片描述

3. 代码

int maxCoins(vector<int>& nums) {
    int n = nums.size();
    nums.insert(nums.begin(), 1); //左侧添1
    nums.push_back(1); //右侧添1
    vector<vector<int>> dp(nums.size(), vector<int>(nums.size(), 0)); //初始化DP数组

    /* 从问题规模从1逐步放大到n */
    for (int len = 1; len <= n; ++len) {
        /* 滑动窗口的方式挪动求解范围的两侧 */
        for (int left = 1; left <= n - len + 1; ++left) {
            int right = left + len - 1;
            /* 在[left, right]确定的滑动窗口中求解 */
            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];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

问题URL:https://leetcode.com/problems/burst-balloons/

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号