Maximize score by multiplying elements of given Array with given multipliers

• Difficulty Level : Hard
• Last Updated : 29 Dec, 2021

Given two arrays array[] and multipliers[] of size N and M where N is always greater than equal to M. There are M operations to be performed. In each operation, choose multiplier[i] and an element from the array arr[] either from the start or the end let’s say K then add multiplier[i]*K to the total score say ans and remove K from the array arr[]. The task is to find the maximum value of the final score ans.

Examples:

Input: array[] = {1, 2, 3}, multipliers[] = {3, 2, 1}, N=3, M=3
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, , adding 1 * 1 = 1 to the score.
The total score is 9 + 4 + 1 = 14.

Input: array[] = {2, 1}, multipliers[] = {0}, N=2, M=1
Output: 0
Explanation: No matter 2 or 1 is chosen, the answer will be 0 because multiplier equals 0.

Naive Approach: The brute force solution is to check each and every pair recursively and find the optimal solution.

Below is the implementation of the above approach

C++

 // C++ program for the above approach#include using namespace std; // Function to find the maximum score// using dynamic programming and// memoizationint getMaxScore(vector& array,                vector& multipliers){   // M is the number of elements needed to pick  int M = multipliers.size(), N = array.size();   int remain = N - M;  vector dp(M + 1, 0);   for (int i = 0; i < M; ++i) {    int mm = multipliers[M - i - 1];     for (int j = 0; j < M - i; ++j) {       dp[j] = max(mm * array[j] + dp[j + 1],                  mm * array[j + remain] + dp[j]);    }    remain += 1;  }  return dp;} // Driver Codeint main(){   vector array = { 1, 2, 3 };  vector multipliers = { 3, 2, 1 };   cout << getMaxScore(array, multipliers);   return 0;} // This code is contributed by rakeshsahni

Java

 // Java program for the above approachpublic class GFG {   // Function to find the maximum score  // using dynamic programming and  // memoization  static int getMaxScore(int []array,int []multipliers)  {     // M is the number of elements needed to pick    int M = multipliers.length;    int N = array.length;     int remain = N - M;    int dp[] = new int[M + 1];     for (int i = 0; i < M; ++i) {      int mm = multipliers[M - i - 1];       for (int j = 0; j < M - i; ++j) {         dp[j] = Math.max(mm * array[j] + dp[j + 1],                         mm * array[j + remain] + dp[j]);      }      remain += 1;    }    return dp;  }   // Driver Code  public static void main (String[] args)  {     int []array = { 1, 2, 3 };    int []multipliers = { 3, 2, 1 };     System.out.println(getMaxScore(array, multipliers));   } } // This code is contributed by AnkThon

Python3

 # Python program for the above approach # Function to find the maximum score# recursively  def getMaxScore(array, multipliers):     # Depth first search    def dfs(start, end, index):        if index == len(multipliers):            return 0         # Pick left        left = multipliers[index] * array[start] + \            dfs(start + 1, end, index + 1)         # Pick right        right = multipliers[index] * array[end] + \            dfs(start, end - 1, index + 1)         return max(right, left)     return dfs(0, len(array) - 1, 0)  # Driver Codeif __name__ == "__main__":     array = [1, 2, 3]    multipliers = [3, 2, 1]     print(getMaxScore(array, multipliers))

C#

 // C# program for the above approachusing System;public class GFG{     // Function to find the maximum score    // using dynamic programming and    // memoization    static int getMaxScore(int[] array, int[] multipliers)    {         // M is the number of elements needed to pick        int M = multipliers.Length;        int N = array.Length;         int remain = N - M;        int[] dp = new int[M + 1];         for (int i = 0; i < M; ++i)        {            int mm = multipliers[M - i - 1];             for (int j = 0; j < M - i; ++j)            {                 dp[j] = Math.Max(mm * array[j] + dp[j + 1],                                 mm * array[j + remain] + dp[j]);            }            remain += 1;        }        return dp;    }     // Driver Code    public static void Main(String[] args)    {         int[] array = { 1, 2, 3 };        int[] multipliers = { 3, 2, 1 };         Console.Write(getMaxScore(array, multipliers));     }} // This code is contributed by gfgking.

Javascript


Output
14

Time Complexity: O(2M)
Auxiliary Space: O(1)

Efficient Approach: The solution is based on dynamic programming as it contains both the properties – optimal substructure and overlapping subproblems. Assume dp[i][j] is the current maximum result that can get from a subarray, where i is the start index and j is the end. At any stage, there are two choices:

pick the first: dp[i + 1][j] + curr_weight * array[i]

pick the last: dp[i][j – 1] + curr_weight * array[j]

The result will be the maximum of both. Follow the steps below to solve the problem using depth-first search and memorization:

• Initialize a variable remain as N-M.
• Initialize an array dp[] of size M+1 with values 0.
• Iterate over the range [0, M) using the variable i and perform the following steps:
• Initialize a variable mm as multipliers[-i-1].
• Iterate over the range [0, M-i) using the variable j and perform the following steps:
• Set the value of dp[j] as the maximum of mm*array[j] + dp[j+1] or mm*array[j+remain] + dp[j].
• Increase the value of remain by 1.
• After performing the above steps, print the value of dp as the answer.

Below is the implementation of the above approach:

C++

 // Java program for the above approach#include using namespace std;   // Function to find the maximum score  // using dynamic programming and  // memoizationint getMaxScore(vector& array,                vector& multipliers){     // M is the number of elements needed to pick    int M = multipliers.size(), N = array.size();     int remain = N - M;    vector dp(M + 1, 0);     for (int i = 0; i < M; ++i) {      int mm = multipliers[M - i - 1];       for (int j = 0; j < M - i; ++j) {         dp[j] = max(mm * array[j] + dp[j + 1],                         mm * array[j + remain] + dp[j]);      }      remain += 1;    }    return dp;  }   // Driver Code  int main ()  {     vector array = { 1, 2, 3 };    vector multipliers = { 3, 2, 1 };     cout << getMaxScore(array, multipliers);   } // This code is contributed by shikhasingrajput

Java

 // Java program for the above approachimport java.util.*;public class GFG {   // Function to find the maximum score  // using dynamic programming and  // memoization  static int getMaxScore(int []array,int []multipliers)  {     // M is the number of elements needed to pick    int M = multipliers.length;    int N = array.length;     int remain = N - M;    int dp[] = new int[M + 1];     for (int i = 0; i < M; ++i) {      int mm = multipliers[M - i - 1];       for (int j = 0; j < M - i; ++j) {         dp[j] = Math.max(mm * array[j] + dp[j + 1],                         mm * array[j + remain] + dp[j]);      }      remain += 1;    }    return dp;  }   // Driver Code  public static void main (String[] args)  {     int []array = { 1, 2, 3 };    int []multipliers = { 3, 2, 1 };     System.out.println(getMaxScore(array, multipliers));   } } // This code is contributed by Samim Hossain Mondal.

Python3

 # Python program for the above approach # Function to find the maximum score# using dynamic programming and# memoizationdef getMaxScore(array, multipliers):     # M is the number of elements needed to pick    M, N = len(multipliers), len(array)    remain = N - M    dp =  * (M + 1)     for i in range(M):        mm = multipliers[-i - 1]        for j in range(M - i):            dp[j] = max(mm * array[j] + dp[j + 1],                        mm * array[j + remain] + dp[j])        remain += 1    return dp # Driver Codeif __name__ == "__main__":     array = [1, 2, 3]    multipliers = [3, 2, 1]     print(getMaxScore(array, multipliers))

C#

 // C# program for the above approachusing System;public class GFG {     // Function to find the maximum score    // using dynamic programming and    // memoization    static int getMaxScore(int[] array, int[] multipliers)    {         // M is the number of elements needed to pick        int M = multipliers.Length;        int N = array.Length;         int remain = N - M;        int[] dp = new int[M + 1];         for (int i = 0; i < M; ++i) {            int mm = multipliers[M - i - 1];             for (int j = 0; j < M - i; ++j) {                 dp[j] = Math.Max(mm * array[j] + dp[j + 1],                                 mm * array[j + remain]                                     + dp[j]);            }            remain += 1;        }        return dp;    }     // Driver Code    public static void Main(string[] args)    {         int[] array = { 1, 2, 3 };        int[] multipliers = { 3, 2, 1 };         Console.WriteLine(getMaxScore(array, multipliers));    }} // This code is contributed by ukasp.

Javascript


Output
14

Time Complexity: O(M*M)
Auxiliary Space: O(M)

My Personal Notes arrow_drop_up