312. 戳气球 - 力扣(LeetCode)

Solution
#include<iostream>
#include<vector>
using namespace std;class Solution {
public:int maxCoins1(vector<int>& nums) {int n = nums.size();vector<int>arr(n + 2);arr[0] = 1, arr[n + 1] = 1;for (int i = 0; i < n; ++i)arr[i + 1] = nums[i];return f1(arr, 1, n);}int maxCoins2(vector<int>& nums) {int n = nums.size();vector<int>arr(n + 2);arr[0] = 1, arr[n + 1] = 1;for (int i = 0; i < n; ++i)arr[i + 1] = nums[i];vector<vector<int>>dp(n + 2, vector<int>(n + 2, -1));return f2(arr, 1, n, dp);}int maxCoins(vector<int>& nums) {return f3(nums);}//递归做法//每次枚举最后一个打爆的气球的位置,因为这样枚举可以很轻易的找到左边和右边的第一个没被打爆的气球int f1(vector<int>& nums, int l, int r) {if (l > r) return 0;int ans = 0;for (int m = l; m <= r; ++m) {ans = max(ans, f1(nums, l, m - 1) + f1(nums, m + 1, r) + nums[l - 1] * nums[r + 1] * nums[m]);}return ans;}//带缓存表的递归int f2(vector<int>& nums, int l, int r, vector<vector<int>>& dp) {if (dp[l][r] != -1) return dp[l][r];if (l > r) return 0;if (l == r) return nums[l - 1] * nums[l] * nums[r + 1];int ans = 0;for (int m = l; m <= r; ++m) {ans = max(ans, f2(nums, l, m - 1, dp) + f2(nums, m + 1, r, dp) + nums[l - 1] * nums[r + 1] * nums[m]);}dp[l][r] = ans;return ans;}//dp做法int f3(vector<int>& nums) {int n = nums.size();vector<int>arr(n + 2);arr[0] = 1, arr[n + 1] = 1;for (int i = 0; i < n; ++i)arr[i + 1] = nums[i];vector<vector<int>>dp(n + 2, vector<int>(n + 2, 0));for (int l = n; l >= 1; --l) {for (int r = l; r <= n; ++r) {int ans = 0;for (int m = l; m <= r; ++m) {ans = max(ans, dp[l][m - 1] + dp[m + 1][r] + arr[l - 1] * arr[r + 1] * arr[m]);}dp[l][r] = ans;}}return dp[1][n];}
};int main() {return 0;
}