 GFG App
Open App Browser
Continue

# Maximize the function by choosing Subsequence of size M

Given an array A[] with size N, Select a subsequence B = {B, B, B, ………B[N] } of size M from given array A[]  (N ≥ M), the task is to find the maximum value of  ∑ i * B[i]  where i is from 1 to M.

The sequence of a given sequence is a sequence that can be derived from the given sequence by deleting some or no elements without changing the order of the remaining elements.

Examples:

Input: A[] = {5, 4, -1, 8}, M = 2
Output: 21
Explanation: Choosing Subsequence B[] = {5, 8} from array A[] which has value ∑ i * B[i] = (1 * 5) + (2 * 8) = 21

Input: A[] = {-3, 1, -4, 1, -5, 9, -2, 6, -5, 3}, M = 4
Output: 54
Explanation:
Choosing Subsequence B[] = {1, 1, 9, 6} from array A[] which has value ∑ i * B[i] = (1 * 1) + (2 * 1) + (3 * 9) + (4 * 6) = 54

Naive approach: The basic way to solve the problem is as follows:

Generating all subsequences of size M by recursive brute force and calculating their   ∑ i * B[i] value and selecting maximum value.

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

Efficient Approach:  The above approach can be optimized based on the following idea:

Dynamic programming can be used to solve this problem.

• dp[i][j] = X, represents the maximum value of ∑ i * B[i] by choosing j elements from first i elements of A[]
• recurrence relation : dp[i][j] = max(dp[i + 1][j + 1] + A[i] * j,  dp[i + 1][j])

it can be observed that there are N * M states but the recursive function is called exponential times. That means that some states are called repeatedly. So the idea is to store the value of states. a This can be done using recursive string intact and just store the value in a HashMap and whenever the function is called, return the value tore without computing .

Follow the steps below to solve the problem:

• Create a recursive function that takes two parameters i representing the current index of A[] and j Number of elements already taken in subsequence B[].
• Call recursive function for both taking i’th element in subsequence B[] and not taking in Subsequence B[]
• Check the base case if exactly M elements are selected in subsequence then return 0 else return an invalid number.
• Create a 2d array of dp[N][M] by initializing all elements with -1.
• If the answer for a particular state is computed then save it in dp[i][j].
• If the answer for a particular state is already computed then just return dp[i][j].

Below is the implementation of the above approach.

## C++

 `// C++ code to implement the approach` `#include ` `using` `namespace` `std;`   `// dp table initialized with - 1` `int` `dp;`   `// recursive function to calculate summation` `// of i * B[i] from 1 to M.` `int` `recur(``int` `i, ``int` `j, ``int` `A[], ``int` `N, ``int` `M)` `{`   `    ``// base case` `    ``if` `(i == N) {` `        ``// if exactly subsequence of size M` `        ``// selected then return 0.` `        ``if` `(j == M + 1)` `            ``return` `0;`   `        ``// else return invalid number` `        ``else` `            ``return` `-1e9;` `    ``}`   `    ``// if answer for current state is already` `    ``// calculated then just return dp[i][j]` `    ``if` `(dp[i][j] != -1)` `        ``return` `dp[i][j];`   `    ``int` `ans = INT_MIN;`   `    ``// calling recursive function to include` `    ``// i'th array element of A[] in B[].` `    ``ans = max(ans, recur(i + 1, j + 1, A, N, M) + A[i] * j);`   `    ``// calling recursive function to not include` `    ``// i'th array element of A[] in B[].` `    ``ans = max(ans, recur(i + 1, j, A, N, M));`   `    ``// save and return dp value` `    ``return` `dp[i][j] = ans;` `}`   `// function to maximize summation of` `// i * B[i] for all i from 1 to M.` `void` `maximizeFunction(``int` `A[], ``int` `N, ``int` `M)` `{` `    ``// filling dp table with -1` `    ``memset``(dp, -1, ``sizeof``(dp));`   `    ``cout << recur(0, 1, A, N, M) << endl;` `}`   `// Driver Code` `int` `main()` `{` `    ``// Input 1` `    ``int` `A[] = { 5, 4, -1, 8 };` `    ``int` `N = ``sizeof``(A) / ``sizeof``(A);` `    ``int` `M = 2;`   `    ``// Function Call` `    ``maximizeFunction(A, N, M);`   `    ``// Input 2` `    ``int` `A1[] = { -3, 1, -4, 1, -5, 9, -2, 6, -5, 3 };` `    ``int` `N1 = ``sizeof``(A1) / ``sizeof``(A1);` `    ``int` `M1 = 4;`   `    ``// Function Call` `    ``maximizeFunction(A1, N1, M1);` `    ``return` `0;` `}`

## Java

 `// Java code to implement the approach`   `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {`   `  ``// dp table initialized with - 1` `  ``static` `int``[][] dp = ``new` `int``[``2001``][``2001``];`   `  ``// recursive function to calculate summation` `  ``// of i * B[i] from 1 to M.` `  ``public` `static` `int` `recur(``int` `i, ``int` `j, ``int``[] A, ``int` `N,` `                          ``int` `M)` `  ``{`   `    ``// base case` `    ``if` `(i == N) {` `      ``// if exactly subsequence of size M` `      ``// selected then return 0.` `      ``if` `(j == M + ``1``)` `        ``return` `0``;`   `      ``// else return invalid number` `      ``else` `        ``return` `-``1000000``;` `    ``}`   `    ``// if answer for current state is already` `    ``// calculated then just return dp[i][j]` `    ``if` `(dp[i][j] != -``1``)` `      ``return` `dp[i][j];`   `    ``int` `ans = Integer.MIN_VALUE;`   `    ``// calling recursive function to include` `    ``// i'th array element of A[] in B[].` `    ``ans = Math.max(ans, recur(i + ``1``, j + ``1``, A, N, M)` `                   ``+ A[i] * j);`   `    ``// calling recursive function to not include` `    ``// i'th array element of A[] in B[].` `    ``ans = Math.max(ans, recur(i + ``1``, j, A, N, M));`   `    ``// save and return dp value` `    ``return` `dp[i][j] = ans;` `  ``}`   `  ``// function to maximize summation of` `  ``// i * B[i] for all i from 1 to M.` `  ``public` `static` `void` `maximizeFunction(``int``[] A, ``int` `N,` `                                      ``int` `M)` `  ``{` `    ``// filling dp table with -1` `    ``for` `(``int` `i = ``0``; i < dp.length; i++) {` `      ``Arrays.fill(dp[i], -``1``);` `    ``}`   `    ``System.out.println(recur(``0``, ``1``, A, N, M));` `  ``}`   `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``// Input 1` `    ``int``[] A = { ``5``, ``4``, -``1``, ``8` `};` `    ``int` `N = A.length;` `    ``int` `M = ``2``;`   `    ``// Function Call` `    ``maximizeFunction(A, N, M);`   `    ``// Input 2` `    ``int``[] A1 = { -``3``, ``1``, -``4``, ``1``, -``5``, ``9``, -``2``, ``6``, -``5``, ``3` `};` `    ``int` `N1 = A1.length;` `    ``int` `M1 = ``4``;`   `    ``// Function Call` `    ``maximizeFunction(A1, N1, M1);` `  ``}` `}`   `// This code is contributed by lokesh.`

## Python3

 `# Python code for the above approach` `# dp table initialized with - 1` `dp ``=` `[[``-``1``] ``*` `2001` `for` `_ ``in` `range``(``2001``)]`   `# recursive function to calculate summation` `# of i * B[i] from 1 to M.` `def` `recur(i, j, A, N, M):` `    ``# base case` `    ``if` `i ``=``=` `N:` `        ``# if exactly subsequence of size M` `        ``# selected then return 0.` `        ``if` `j ``=``=` `M ``+` `1``:` `            ``return` `0`   `        ``# else return invalid number` `        ``else``:` `            ``return` `-``1e9`   `    ``# if answer for current state is already` `    ``# calculated then just return dp[i][j]` `    ``if` `dp[i][j] !``=` `-``1``:` `        ``return` `dp[i][j]`   `    ``ans ``=` `float``(``"-inf"``)`   `    ``# calling recursive function to include` `    ``# i'th array element of A[] in B[].` `    ``ans ``=` `max``(ans, recur(i ``+` `1``, j ``+` `1``, A, N, M) ``+` `A[i] ``*` `j)`   `    ``# calling recursive function to not include` `    ``# i'th array element of A[] in B[].` `    ``ans ``=` `max``(ans, recur(i ``+` `1``, j, A, N, M))`   `    ``# save and return dp value` `    ``dp[i][j] ``=` `ans` `    ``return` `ans`   `# function to maximize summation of` `# i * B[i] for all i from 1 to M.` `def` `maximize_function(A, N, M):` `    ``# filling dp table with -1` `    ``for` `i ``in` `range``(``2001``):` `        ``for` `j ``in` `range``(``2001``):` `            ``dp[i][j] ``=` `-``1`   `    ``print``(recur(``0``, ``1``, A, N, M))`   `# Driver Code`   `    ``# Input 1` `A ``=` `[``5``, ``4``, ``-``1``, ``8``]` `N ``=` `len``(A)` `M ``=` `2`   `# Function Call` `maximize_function(A, N, M)`   `# Input 2` `A1 ``=` `[``-``3``, ``1``, ``-``4``, ``1``, ``-``5``, ``9``, ``-``2``, ``6``, ``-``5``, ``3``]` `N1 ``=` `len``(A1)` `M1 ``=` `4`   `# Function Call` `maximize_function(A1, N1, M1)`   `# This code is contributed by Potta Lokesh`

## C#

 `using` `System;` `using` `System.Linq;`   `class` `GFG {` `    `  `    ``// dp table initialized with - 1` `    ``static` `int``[,] dp=``new` `int``[2001, 2001];` `    `  `    ``// recursive function to calculate summation` `    ``// of i * B[i] from 1 to M.` `    ``static` `int` `recur(``int` `i, ``int` `j, ``int``[] A, ``int` `N, ``int` `M)` `    ``{` `    `  `        ``// base case` `        ``if` `(i == N) {` `            ``// if exactly subsequence of size M` `            ``// selected then return 0.` `            ``if` `(j == M + 1)` `                ``return` `0;` `    `  `            ``// else return invalid number` `            ``else` `                ``return` `-1000000000;` `        ``}` `    `  `        ``// if answer for current state is already` `        ``// calculated then just return dp[i][j]` `        ``if` `(dp[i,j] != -1)` `            ``return` `dp[i,j];` `    `  `        ``int` `ans = -2147483648;` `    `  `        ``// calling recursive function to include` `        ``// i'th array element of A[] in B[].` `        ``ans = Math.Max(ans, recur(i + 1, j + 1, A, N, M) + A[i] * j);` `    `  `        ``// calling recursive function to not include` `        ``// i'th array element of A[] in B[].` `        ``ans = Math.Max(ans, recur(i + 1, j, A, N, M));` `    `  `        ``// save and return dp value` `        ``return` `dp[i,j] = ans;` `    ``}` `    `  `    ``// function to maximize summation of` `    ``// i * B[i] for all i from 1 to M.` `    ``static` `void` `maximizeFunction(``int``[] A, ``int` `N, ``int` `M)` `    ``{` `        ``// filling dp table with -1` `        ``for``(``int` `i=0; i<2001; i++)` `        ``{` `            ``for``(``int` `j=0; j<2001; j++)` `                ``dp[i,j]=-1;` `        ``}` `    `  `        ``Console.Write(recur(0, 1, A, N, M)+``"\n"``);` `    ``}` `    `  `    ``// Driver Code` `    ``public` `static` `void` `Main(``string``[] args) ` `    ``{` `        ``// Input 1` `        ``int``[] A = { 5, 4, -1, 8 };` `        ``int` `N = A.Length;` `        ``int` `M = 2;` `    `  `        ``// Function Call` `        ``maximizeFunction(A, N, M);` `    `  `        ``// Input 2` `        ``int``[] A1 = { -3, 1, -4, 1, -5, 9, -2, 6, -5, 3 };` `        ``int` `N1 = A1.Length;` `        ``int` `M1 = 4;` `    `  `        ``// Function Call` `        ``maximizeFunction(A1, N1, M1);` `    ``}` `}`   `// This code is contributed by ratiagarwal.`

## Javascript

 `// Javascript code to implement the approach`   `// dp table initialized with - 1` `let dp = ``new` `Array(2001);`   `// recursive function to calculate summation` `// of i * B[i] from 1 to M.` `function` `recur(i, j, A, N, M)` `{`   `    ``// base case` `    ``if` `(i == N) {` `        ``// if exactly subsequence of size M` `        ``// selected then return 0.` `        ``if` `(j == M + 1)` `            ``return` `0;`   `        ``// else return invalid number` `        ``else` `            ``return` `-1e9;` `    ``}`   `    ``// if answer for current state is already` `    ``// calculated then just return dp[i][j]` `    ``if` `(dp[i][j] != -1)` `        ``return` `dp[i][j];`   `    ``let ans = Number.MIN_SAFE_INTEGER;`   `    ``// calling recursive function to include` `    ``// i'th array element of A[] in B[].` `    ``ans = Math.max(ans, recur(i + 1, j + 1, A, N, M) + A[i] * j);`   `    ``// calling recursive function to not include` `    ``// i'th array element of A[] in B[].` `    ``ans = Math.max(ans, recur(i + 1, j, A, N, M));`   `    ``// save and return dp value` `    ``return` `dp[i][j] = ans;` `}`   `// function to maximize summation of` `// i * B[i] for all i from 1 to M.` `function` `maximizeFunction(A, N, M)` `{` `    ``// filling dp table with -1` `    ``for``(let i=0; i<2001; i++)` `        ``dp[i]= ``new` `Array(2001).fill(-1);` `    ``document.write(recur(0, 1, A, N, M));` `}`   `// Driver Code` `    ``// Input 1` `    ``let A = [ 5, 4, -1, 8 ];` `    ``let N = A.length;` `    ``let M = 2;`   `    ``// Function Call` `    ``maximizeFunction(A, N, M);`   `    ``// Input 2` `    ``let A1 = [ -3, 1, -4, 1, -5, 9, -2, 6, -5, 3 ];` `    ``let N1 = A1.length;` `    ``let M1 = 4;`   `    ``// Function Call` `    ``maximizeFunction(A1, N1, M1);`

Output

```21
54```

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

Related Articles :

My Personal Notes arrow_drop_up