# Maximize score by multiplying elements of given Array with given multipliers

• Difficulty Level : Hard
• Last Updated : 30 Nov, 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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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 choosen, 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``// memoization``int` `getMaxScore(vector<``int``>& array,``                ``vector<``int``>& multipliers)``{` `  ``// M is the number of elements needed to pick``  ``int` `M = multipliers.size(), N = array.size();` `  ``int` `remain = N - M;``  ``vector<``int``> 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<``int``> array = { 1, 2, 3 };``  ``vector<``int``> multipliers = { 3, 2, 1 };` `  ``cout << getMaxScore(array, multipliers);` `  ``return` `0;``}` `// This code is contributed by rakeshsahni`

## Java

 `// Java program for the above approach``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[``0``];``  ``}` `  ``// 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 Code``if` `__name__ ``=``=` `"__main__"``:` `    ``array ``=` `[``1``, ``2``, ``3``]``    ``multipliers ``=` `[``3``, ``2``, ``1``]` `    ``print``(getMaxScore(array, multipliers))`

## C#

 `// C# program for the above approach``using` `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:

## Java

 `// Java program for the above approach``import` `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[``0``];``  ``}` `  ``// 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``# memoization``def` `getMaxScore(array, multipliers):` `    ``# M is the number of elements needed to pick``    ``M, N ``=` `len``(multipliers), ``len``(array)``    ``remain ``=` `N ``-` `M``    ``dp ``=` `[``0``] ``*` `(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[``0``]` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``array ``=` `[``1``, ``2``, ``3``]``    ``multipliers ``=` `[``3``, ``2``, ``1``]` `    ``print``(getMaxScore(array, multipliers))`

## Javascript

 ``
Output
`14`

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

My Personal Notes arrow_drop_up