Maximize score by multiplying elements of given Array with given multipliers
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, [1], 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[0] 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++
#include <bits/stdc++.h>
using namespace std;
int getMaxScore(vector< int >& array,
vector< int >& multipliers)
{
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[0];
}
int main()
{
vector< int > array = { 1, 2, 3 };
vector< int > multipliers = { 3, 2, 1 };
cout << getMaxScore(array, multipliers);
return 0;
}
|
Java
public class GFG {
static int getMaxScore( int []array, int []multipliers)
{
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 ];
}
public static void main (String[] args)
{
int []array = { 1 , 2 , 3 };
int []multipliers = { 3 , 2 , 1 };
System.out.println(getMaxScore(array, multipliers));
}
}
|
Python3
def getMaxScore(array, multipliers):
def dfs(start, end, index):
if index = = len (multipliers):
return 0
left = multipliers[index] * array[start] + \
dfs(start + 1 , end, index + 1 )
right = multipliers[index] * array[end] + \
dfs(start, end - 1 , index + 1 )
return max (right, left)
return dfs( 0 , len (array) - 1 , 0 )
if __name__ = = "__main__" :
array = [ 1 , 2 , 3 ]
multipliers = [ 3 , 2 , 1 ]
print (getMaxScore(array, multipliers))
|
C#
using System;
public class GFG
{
static int getMaxScore( int [] array, int [] multipliers)
{
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];
}
public static void Main(String[] args)
{
int [] array = { 1, 2, 3 };
int [] multipliers = { 3, 2, 1 };
Console.Write(getMaxScore(array, multipliers));
}
}
|
Javascript
<script>
function getMaxScore(array, multipliers) {
let M = multipliers.length, N = array.length;
let remain = N - M;
let dp = new Array(M + 1).fill(0);
for (let i = 0; i < M; ++i) {
let mm = multipliers[M - i - 1];
for (let 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];
}
let array = [1, 2, 3];
let multipliers = [3, 2, 1];
document.write(getMaxScore(array, multipliers));
</script>
|
Time Complexity: O(2M)
Auxiliary Space: O(M)
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[0] as the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int getMaxScore(vector< int >& array,
vector< int >& multipliers)
{
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[0];
}
int main ()
{
vector< int > array = { 1, 2, 3 };
vector< int > multipliers = { 3, 2, 1 };
cout << getMaxScore(array, multipliers);
}
|
Java
import java.util.*;
public class GFG {
static int getMaxScore( int []array, int []multipliers)
{
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 ];
}
public static void main (String[] args)
{
int []array = { 1 , 2 , 3 };
int []multipliers = { 3 , 2 , 1 };
System.out.println(getMaxScore(array, multipliers));
}
}
|
Python3
def getMaxScore(array, multipliers):
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 ]
if __name__ = = "__main__" :
array = [ 1 , 2 , 3 ]
multipliers = [ 3 , 2 , 1 ]
print (getMaxScore(array, multipliers))
|
C#
using System;
public class GFG {
static int getMaxScore( int [] array, int [] multipliers)
{
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];
}
public static void Main( string [] args)
{
int [] array = { 1, 2, 3 };
int [] multipliers = { 3, 2, 1 };
Console.WriteLine(getMaxScore(array, multipliers));
}
}
|
Javascript
<script>
function getMaxScore(array, multipliers) {
M = multipliers.length
N = array.length
remain = N - M
dp = new Array(M + 1).fill(0)
for (let i = 0; i < M; i++) {
mm = multipliers[M - i - 1]
for (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]
}
array = [1, 2, 3]
multipliers = [3, 2, 1]
document.write(getMaxScore(array, multipliers))
</script>
|
Time Complexity: O(M*M)
Auxiliary Space: O(M)
Last Updated :
20 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...