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++ program for the above approach #include <bits/stdc++.h> 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[0];
} // 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 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 |
# 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# 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[0];
}
// 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. |
<script> // Javascript program for the above approach // Function to find the maximum score // using dynamic programming and // memoization function getMaxScore(array, multipliers) {
// M is the number of elements needed to pick
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];
} // Driver Code let array = [1, 2, 3]; let multipliers = [3, 2, 1]; document.write(getMaxScore(array, multipliers)); // This code is contributed by gfgking </script> |
14
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:
// Java program for the above approach #include <bits/stdc++.h> 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[0];
}
// Driver Code
int main ()
{
vector< int > array = { 1, 2, 3 };
vector< int > multipliers = { 3, 2, 1 };
cout << getMaxScore(array, multipliers);
}
// This code is contributed by shikhasingrajput |
// 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. |
# 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))
|
// 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[0];
}
// 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. |
<script> // JavaScript Program to implement
// the above approach
//Function to find the maximum score
//using dynamic programming and
//memoization
function getMaxScore(array, multipliers) {
//M is the number of elements needed to pick
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))
// This code is contributed by Potta Lokesh
</script>
|
14
Time Complexity: O(M*M)
Auxiliary Space: O(M)