Maximum Score from Performing Multiplication Operations

hard dp memoization

Problem

Given arrays nums and multipliers, on step i pick either nums[front] or nums[back], multiply by multipliers[i], add to score, and remove that element. Maximize total score.

Inputnums = [1,2,3], multipliers = [3,2,1]
Output14
Pick 1·3 + 2·2 + 3·... pattern → max 14.

def maximum_score(nums, multipliers):
    m = len(multipliers)
    n = len(nums)
    dp = [[0] * (m + 1) for _ in range(m + 1)]
    for i in range(m - 1, -1, -1):
        for left in range(i, -1, -1):
            right = n - 1 - (i - left)
            dp[i][left] = max(
                nums[left] * multipliers[i] + dp[i+1][left+1],
                nums[right] * multipliers[i] + dp[i+1][left]
            )
    return dp[0][0]
function maximumScore(nums, multipliers) {
  const m = multipliers.length, n = nums.length;
  const dp = Array.from({length: m + 1}, () => new Array(m + 1).fill(0));
  for (let i = m - 1; i >= 0; i--) {
    for (let left = i; left >= 0; left--) {
      const right = n - 1 - (i - left);
      dp[i][left] = Math.max(
        nums[left] * multipliers[i] + dp[i+1][left+1],
        nums[right] * multipliers[i] + dp[i+1][left]
      );
    }
  }
  return dp[0][0];
}
class Solution {
    public int maximumScore(int[] nums, int[] multipliers) {
        int m = multipliers.length, n = nums.length;
        int[][] dp = new int[m + 1][m + 1];
        for (int i = m - 1; i >= 0; i--) {
            for (int left = i; left >= 0; left--) {
                int right = n - 1 - (i - left);
                dp[i][left] = Math.max(
                    nums[left] * multipliers[i] + dp[i+1][left+1],
                    nums[right] * multipliers[i] + dp[i+1][left]
                );
            }
        }
        return dp[0][0];
    }
}
int maximumScore(vector<int>& nums, vector<int>& multipliers) {
    int m = multipliers.size(), n = nums.size();
    vector<vector<int>> dp(m + 1, vector<int>(m + 1, 0));
    for (int i = m - 1; i >= 0; i--) {
        for (int left = i; left >= 0; left--) {
            int right = n - 1 - (i - left);
            dp[i][left] = max(
                nums[left] * multipliers[i] + dp[i+1][left+1],
                nums[right] * multipliers[i] + dp[i+1][left]
            );
        }
    }
    return dp[0][0];
}
Time: O(m²) Space: O(m²)