classSolution { public: intmaxCoins(vector<int>& nums){ int n = nums.size(); vector<int> arr(n + 2, 1); for (int i = 1; i <= n; i++) arr[i] = nums[i - 1];
vector<vector<int>> memo(n + 2, vector<int>(n + 2, -1)); function<int(int, int)> dfs = [&](int left, int right) -> int { if (right - left <= 1) return0; if (memo[left][right] != -1) return memo[left][right]; int res = 0; for (int i = left + 1; i < right; i++) { int cur = arr[left] * arr[i] * arr[right]; cur += dfs(left, i) + dfs(i, right); res = max(res, cur); } return memo[left][right] = res; };
returndfs(0, n + 1); } };
方法二:填表法 / Bottom-up DP
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defmaxCoins(self, nums: List[int]) -> int: n = len(nums) nums = [1] + nums + [1] f = [[0] * (n + 2) for _ inrange(n + 2)] for ln inrange(1, n + 1): # number of balloons inside (l, r) for l inrange(n - ln + 1): r = l + ln + 1 for m inrange(l + 1, r): f[l][r] = max( f[l][r], f[l][m] + f[m][r] + nums[l] * nums[m] * nums[r], ) return f[0][n + 1]
classSolution { public: intmaxCoins(vector<int>& nums){ int n = nums.size(); vector<int> arr(n + 2, 1); for (int i = 1; i <= n; i++) arr[i] = nums[i - 1];
vector<vector<int>> dp(n + 2, vector<int>(n + 2, 0)); for (int length = 3; length <= n + 2; length++) { for (int left = 0; left <= n + 2 - length; left++) { int right = left + length - 1; for (int i = left + 1; i < right; i++) { int cur = dp[left][i] + dp[i][right] + arr[left] * arr[i] * arr[right]; dp[left][right] = max(dp[left][right], cur); } } }
return dp[0][n + 1]; } };
寫在最後
Cover Image Credit
The cover image was created by @たろたろ. All rights belong to the original artist.
It is used here only as a non-commercial cover illustration for this note. I do not claim ownership of the artwork.
If you are the copyright holder and believe this usage is inappropriate, please contact me by email or leave a comment. I will remove the image promptly.
事實上,這題也可以視為是 Matrix Chain Multiplication 的變形題,只需要在最前面和最後面加上一個 1,並且從取 min 改為取 max 即可。