赞
踩
给定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
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];
}

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。