Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/1770.html
1770. Maximum Score from Performing Multiplication Operations
Level
Medium
Description
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 i-th
operation (1-indexed), you will:
- Choose one integer
x
from either the start or the end of the arraynums
. - Add
multipliers[i] * x
to your score. - Remove
x
from the array nums.
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.length
m == multipliers.length
1 <= m <= 10^3
m <= n <= 10^5
-1000 <= nums[i], multipliers[i] <= 1000
Solution
Use dynamic programming. Create a 2D array dp
of m + 1
rows and n
columns, where dp[i][j]
represents the maximum score using the last i
multiplers for the subarray starting from index j
. The base case is when i = 1
. The final result is dp[m][0]
.
To optimize memory, use a 1D array instead, which stores only the last row of the original dp
array.
-
class Solution { public int maximumScore(int[] nums, int[] multipliers) { int n = nums.length, m = multipliers.length; int[] dp = new int[n]; int minWindow = n - m + 1; for (int j = minWindow - 1; j < n; j++) { int start = j - minWindow + 1; dp[start] = Math.max(nums[start] * multipliers[m - 1], nums[j] * multipliers[m - 1]); } for (int i = 2; i <= m; i++) { int[] dpNew = new int[n]; int window = n - m + i; for (int j = window - 1; j < n; j++) { int start = j - window + 1; dpNew[start] = Math.max(dp[start + 1] + nums[start] * multipliers[m - i], dp[start] + nums[j] * multipliers[m - i]); } dp = dpNew; } return dp[0]; } } ############ class Solution { private Integer[][] f; private int[] multipliers; private int[] nums; private int n; private int m; public int maximumScore(int[] nums, int[] multipliers) { n = nums.length; m = multipliers.length; f = new Integer[m][m]; this.nums = nums; this.multipliers = multipliers; return dfs(0, 0); } private int dfs(int i, int j) { if (i >= m || j >= m || (i + j) >= m) { return 0; } if (f[i][j] != null) { return f[i][j]; } int k = i + j; int a = dfs(i + 1, j) + nums[i] * multipliers[k]; int b = dfs(i, j + 1) + nums[n - 1 - j] * multipliers[k]; f[i][j] = Math.max(a, b); return f[i][j]; } }
-
// OJ: https://leetcode.com/problems/maximum-score-from-performing-multiplication-operations/ // Time: O(M^2) // Space: O(M^2) class Solution { int memo[1001][1001] = {}; int dfs(vector<int> &A, vector<int> &M, int i, int j) { if (j == M.size()) return 0; if (memo[j][i]) return memo[j][i]; return memo[j][i] = max(A[i] * M[j] + dfs(A, M, i + 1, j + 1), A[A.size() - j + i - 1] * M[j] + dfs(A, M, i, j + 1)); } public: int maximumScore(vector<int>& A, vector<int>& M) { return dfs(A, M, 0, 0); } };
-
class Solution: def maximumScore(self, nums: List[int], multipliers: List[int]) -> int: @cache def f(i, j, k): if k >= m or i >= n or j < 0: return 0 a = f(i + 1, j, k + 1) + nums[i] * multipliers[k] b = f(i, j - 1, k + 1) + nums[j] * multipliers[k] return max(a, b) n = len(nums) m = len(multipliers) return f(0, n - 1, 0) ############ # 1770. Maximum Score from Performing Multiplication Operations # https://leetcode.com/problems/maximum-score-from-performing-multiplication-operations/ class Solution: def maximumScore(self, nums: List[int], muls: List[int]) -> int: n, m = len(nums), len(muls) @lru_cache(2000) def dp(l, i): if i == m: return 0 pickLeft = dp(l+1, i+1) + nums[l] * muls[i] # Pick the left side pickRight = dp(l, i+1) + nums[n-(i-l)-1] * muls[i] # Pick the right side return max(pickLeft, pickRight) return dp(0, 0)
-
func maximumScore(nums []int, multipliers []int) int { n, m := len(nums), len(multipliers) f := make([][]int, m) for i := range f { f[i] = make([]int, m) for j := range f[i] { f[i][j] = 1 << 30 } } var dfs func(i, j int) int dfs = func(i, j int) int { if i >= m || j >= m || i+j >= m { return 0 } if f[i][j] != 1<<30 { return f[i][j] } k := i + j a := dfs(i+1, j) + nums[i]*multipliers[k] b := dfs(i, j+1) + nums[n-j-1]*multipliers[k] f[i][j] = max(a, b) return f[i][j] } return dfs(0, 0) } func max(a, b int) int { if a > b { return a } return b }
-
function maximumScore(nums: number[], multipliers: number[]): number { const inf = 1 << 30; const n = nums.length; const m = multipliers.length; const f = new Array(m + 1).fill(0).map(() => new Array(m + 1).fill(-inf)); f[0][0] = 0; let ans = -inf; for (let i = 0; i <= m; ++i) { for (let j = 0; j <= m - i; ++j) { const k = i + j - 1; if (i > 0) { f[i][j] = Math.max( f[i][j], f[i - 1][j] + nums[i - 1] * multipliers[k], ); } if (j > 0) { f[i][j] = Math.max( f[i][j], f[i][j - 1] + nums[n - j] * multipliers[k], ); } if (i + j === m) { ans = Math.max(ans, f[i][j]); } } } return ans; }