1770. Maximum Score from Performing Multiplication Operations
You are given two integer arrays nums and multipliers of size n and m respectively, where n >= m. The arrays are 1-indexed.
You begin with a score of 0. You want to perform exactly m operations. On the ith operation (1-indexed), you will:
- Choose one integer
xfrom either the start or the end of the arraynums. - Add
multipliers[i] * xto your score. - Remove
xfrom the arraynums.
Return the maximum score after performing m operations.
Example 1:
Input: nums = [1,2,3], multipliers = [3,2,1] Output: 14 Explanation: An optimal solution is as follows: - Choose from the end, [1,2,3], adding 3 * 3 = 9 to the score. - Choose from the end, [1,2], adding 2 * 2 = 4 to the score. - Choose from the end, [1], adding 1 * 1 = 1 to the score. The total score is 9 + 4 + 1 = 14.
Example 2:
Input: nums = [-5,-3,-3,-2,7,1], multipliers = [-10,-5,3,4,6] Output: 102 Explanation: An optimal solution is as follows: - Choose from the start, [-5,-3,-3,-2,7,1], adding -5 * -10 = 50 to the score. - Choose from the start, [-3,-3,-2,7,1], adding -3 * -5 = 15 to the score. - Choose from the start, [-3,-2,7,1], adding -3 * 3 = -9 to the score. - Choose from the end, [-2,7,1], adding 1 * 4 = 4 to the score. - Choose from the end, [-2,7], adding 7 * 6 = 42 to the score. The total score is 50 + 15 - 9 + 4 + 42 = 102.
Constraints:
n == nums.lengthm == multipliers.length1 <= m <= 103m <= n <= 105-1000 <= nums[i], multipliers[i] <= 1000
class Solution { int n, m; int[] nums, muls; Integer[][][] memo; public int maximumScore(int[] nums, int[] muls) { n = nums.length; m = muls.length; this.nums= nums; this.muls = muls; this.memo = new Integer[m][m][n]; return dp(0, 0, n - 1); } private int dp(int l, int i, int r) { if (i == m) return 0; // Picked enough m elements if (memo[l][i][r] != null) return memo[l][i][r]; int pickLeft = dp(l+1, i+1, r) + nums[l] * muls[i]; // Pick the left side int pickRight = dp(l, i+1, r - 1) + nums[r] * muls[i]; // Pick the right side return memo[l][i][r] = Math.max(pickLeft, pickRight); } }
https://leetcode.com/problems/maximum-score-from-performing-multiplication-operations/discuss/1075469/JavaC%2B%2BPython-3-Top-Down-DP-O(m2)-Clean-and-Concise
https://leetcode.com/problems/maximum-score-from-performing-multiplication-operations/discuss/1075492/Java-Detailed-Explanation-DP-Optimize-Space
public int maximumScore(int[] nums, int[] multipliers) { int N = nums.length, M = multipliers.length; return helper(nums, multipliers, 0, N - 1, new Integer[M][M]); } private int helper(int[] nums, int[] multipliers, int i, int j, Integer[][] dp) { int N = nums.length, M = multipliers.length; int index = (i - 0) + (N - 1 - j); if (index == M) return 0; if (dp[i][j - (N - M)] != null) return dp[i][j - (N - M)]; int res = Math.max(nums[i] * multipliers[index] + helper(nums, multipliers, i + 1, j, dp), nums[j] * multipliers[index] + helper(nums, multipliers, i, j - 1, dp)); return dp[i][j - (N - M)] = res; }
这个index咋算的看了好久才反应过来:index,是ith step,是算到了第几步,那么前面的步骤是咋算出来的?要么pick左边,要么右边是不是?通过l和r的位置可以得出当前计算了多少步:(i - 0)是选了几次左边,(N - 1 - j)是选了几次右边,两个之和就是index了。
https://leetcode.com/problems/maximum-score-from-performing-multiplication-operations/discuss/1075697/JAVA-Bottom-Up-DP-O(m2)-Runtime

public int maximumScore(int[] nums, int[] multipliers) { int m = multipliers.length; int[][] dp = new int[m+1][m+1]; dp[0][0] = 0; int result = Integer.MIN_VALUE; for(int left = 0; left <= m; ++left) { for (int right = 0; right <= m; right++) { int index = right + left -1; if (index < 0 || index >= m) continue; if (left == 0) { dp[left][right] = dp[left][right -1] + nums[nums.length - right] * multipliers[index]; } else if (right == 0) { dp[left][right] = dp[left -1][right] + nums[left -1] * multipliers[index]; } else { int a = dp[left -1][right] + nums[left -1] * multipliers[index]; int b = dp[left][right -1] + nums[nums.length - right] * multipliers[index]; dp[left][right] = Math.max(a, b); } if (index == m-1) { result = Math.max(result, dp[left][right]); } } } return result; }

浙公网安备 33010602011771号