Open In App

Maximum subsequence sum possible by multiplying each element by its index

Given an array arr[] consisting of N integers, the task is to find the maximum subsequence sum by multiplying each element of the resultant subsequence by its index(1-based indexing).

Examples:



Input: arr[] = {-1, 2, -10, 4, -20} 
Output: 15 
Explanation: 
For the subsequence {-1, 2, 4}, sum of the given subsequence after performing the given operations = 1*(-1) + 2*2 + 3*4 = 15, which is maximum possible.

Input: arr[] = {1, 0, -1, 2} 
Output:
Explanation: 
For the subsequence {1, 0, 2}, sum of the given subsequence after performing the given operations = 1*1 + 2*0 + 3*2 = 7, which is maximum possible.



Naive Approach: The idea is to generate all possible subsequences from the array using recursion and calculate the required sum for each subsequence and print the maximum sum. 

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

Efficient Approach: The above approach can be optimized using Dynamic Programming as the problem contains many overlapping subproblems. Below are the steps:

 dp[i][j] = max(a[i] * j + maximumSum(j + 1, i + 1), maximumSum(j, i + 1)) 

Below is the implementation of the above approach:




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Initialize dp array
int dp[1005][1005];
 
// Function to find the maximum
// sum of the subsequence formed
int maximumSumUtil(int a[], int index,
                   int count, int n)
{
    // Base Case
    if (index > n || count > n + 1) {
        return 0;
    }
 
    // If already calculated
    // state occurs
    if (dp[index][count] != -1)
        return dp[index][count];
 
    // Include the current element
    int ans1 = maximumSumUtil(a, index + 1,
                              count + 1, n)
               + a[index] * count;
 
    // Exclude the current element
    int ans2 = maximumSumUtil(a, index + 1,
                              count, n);
 
    // Update the maximum ans
    return (dp[index][count]
            = max(ans1, ans2));
}
 
// Function to calculate maximum sum
// of the subsequence obtained
int maximumSum(int arr[], int N)
{
    // Initialise the dp array with -1
    memset(dp, -1, sizeof(dp));
 
    // Print the maximum sum possible
    cout << maximumSumUtil(arr, 0, 1,
                           N - 1);
}
 
// Driver Code
int main()
{
    // Given array
    int arr[] = { -1, 2, -10, 4, -20 };
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    maximumSum(arr, N);
 
    return 0;
}




// Java program for
// the above approach
import java.util.*;
class GFG{
 
// Initialize dp array
static int [][]dp = new int[1005][1005];
 
// Function to find the maximum
// sum of the subsequence formed
static int maximumSumUtil(int a[], int index,
                          int count, int n)
{
  // Base Case
  if (index > n || count > n + 1)
  {
    return 0;
  }
 
  // If already calculated
  // state occurs
  if (dp[index][count] != -1)
    return dp[index][count];
 
  // Include the current element
  int ans1 = maximumSumUtil(a, index + 1,
                            count + 1, n) +
                            a[index] * count;
 
  // Exclude the current element
  int ans2 = maximumSumUtil(a, index + 1,
                            count, n);
 
  // Update the maximum ans
  return (dp[index][count] =
          Math.max(ans1, ans2));
}
 
// Function to calculate maximum sum
// of the subsequence obtained
static void maximumSum(int arr[], int N)
{
  // Initialise the dp array with -1
  for(int i = 0; i < 1005; i++)
  {
    for (int j = 0; j < 1005; j++)
    {
      dp[i][j] = -1;
    }
  }
 
  // Print the maximum sum possible
  System.out.print(maximumSumUtil(arr, 0,
                                  1, N - 1));
}
 
// Driver Code
public static void main(String[] args)
{
  // Given array
  int arr[] = {-1, 2, -10, 4, -20};
 
  // Size of the array
  int N = arr.length;
 
  // Function Call
  maximumSum(arr, N);
}
}
 
// This code is contributed by 29AjayKumar




# Python3 program for the above approach
 
# Initialize dp array
dp = [[-1 for x in range(1005)]
          for y in range(1005)]
 
# Function to find the maximum
# sum of the subsequence formed
def maximumSumUtil(a, index, count, n):
 
    # Base Case
    if (index > n or count > n + 1):
        return 0
 
    # If already calculated
    # state occurs
    if (dp[index][count] != -1):
        return dp[index][count]
 
    # Include the current element
    ans1 = (maximumSumUtil(a, index + 1,
                              count + 1, n) +
                           a[index] * count)
 
    # Exclude the current element
    ans2 = maximumSumUtil(a, index + 1,
                          count, n)
 
    # Update the maximum ans
    dp[index][count] = max(ans1, ans2)
 
    return dp[index][count]
 
# Function to calculate maximum sum
# of the subsequence obtained
def maximumSum(arr, N):
 
    # Print the maximum sum possible
    print(maximumSumUtil(arr, 0, 1,
                             N - 1))
 
# Driver Code
 
# Given array
arr = [ -1, 2, -10, 4, -20 ]
 
# Size of the array
N = len(arr)
 
# Function call
maximumSum(arr, N)
 
# This code is contributed by Shivam Singh




// C# program for
// the above approach
using System;
class GFG{
 
// Initialize dp array
static int [,]dp = new int[1005, 1005];
 
// Function to find the maximum
// sum of the subsequence formed
static int maximumSumUtil(int []a, int index,
                          int count, int n)
{
  // Base Case
  if (index > n || count > n + 1)
  {
    return 0;
  }
 
  // If already calculated
  // state occurs
  if (dp[index, count] != -1)
    return dp[index, count];
 
  // Include the current element
  int ans1 = maximumSumUtil(a, index + 1,
                            count + 1, n) +
                            a[index] * count;
 
  // Exclude the current element
  int ans2 = maximumSumUtil(a, index + 1,
                            count, n);
 
  // Update the maximum ans
  return (dp[index, count] =
          Math.Max(ans1, ans2));
}
 
// Function to calculate maximum sum
// of the subsequence obtained
static void maximumSum(int []arr, int N)
{
  // Initialise the dp array with -1
  for(int i = 0; i < 1005; i++)
  {
    for (int j = 0; j < 1005; j++)
    {
      dp[i, j] = -1;
    }
  }
 
  // Print the maximum sum possible
  Console.Write(maximumSumUtil(arr, 0,
                               1, N - 1));
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given array
  int []arr = {-1, 2, -10, 4, -20};
 
  // Size of the array
  int N = arr.Length;
 
  // Function Call
  maximumSum(arr, N);
}
}
 
// This code is contributed by Rajput-Ji




<script>
 
// JavaScript program for
// the above approach
 
// Let initialize dp array
let dp = new Array(1005);
 
// Loop to create 2D array using 1D array
for (var i = 0; i < dp.length; i++) {
    dp[i] = new Array(2);
}
  
// Function to find the maximum
// sum of the subsequence formed
function maximumSumUtil(a, index,
                          count, n)
{
  // Base Case
  if (index > n || count > n + 1)
  {
    return 0;
  }
  
  // If already calculated
  // state occurs
  if (dp[index][count] != -1)
    return dp[index][count];
  
  // Include the current element
  let ans1 = maximumSumUtil(a, index + 1,
                            count + 1, n) +
                            a[index] * count;
  
  // Exclude the current element
  let ans2 = maximumSumUtil(a, index + 1,
                            count, n);
  
  // Update the maximum ans
  return (dp[index][count] =
          Math.max(ans1, ans2));
}
  
// Function to calculate maximum sum
// of the subsequence obtained
function maximumSum(arr, N)
{
  // Initialise the dp array with -1
  for(let i = 0; i < 1005; i++)
  {
    for (let j = 0; j < 1005; j++)
    {
      dp[i][j] = -1;
    }
  }
  
  // Print the maximum sum possible
  document.write(maximumSumUtil(arr, 0,
                                  1, N - 1));
}
 
// Driver code
 
  // Given array
  let arr = [-1, 2, -10, 4, -20];
  
  // Size of the array
  let N = arr.length;
  
  // Function Call
  maximumSum(arr, N);
                             
</script>

Output: 
15

Time Complexity: O(N2
Auxiliary Space: O(N2)

Efficient approach : Using DP Tabulation method ( Iterative approach )

The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.

Steps to solve this problem :

Implementation :




// C++ program for above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum
// sum of the subsequence formed
int maximumSum(int a[], int n)
{  
     
    // initialize Dp to store computation of subproblems
    int dp[n+1][n+2];
    memset(dp, 0, sizeof(dp));
 
 
    // Traverse the array in reverse order and fill the dp table
    for(int i=n-1; i>=0; i--){
        for(int j=1; j<=n+1; j++){
            // Include the current element
            int ans1 = dp[i+1][j+1] + a[i]*j;
            // Exclude the current element
            int ans2 = dp[i+1][j];
            // Update the maximum ans
            dp[i][j] = max(ans1, ans2);
        }
    }
    // Return the answer
    return dp[0][1];
}
 
int main()
{
    // Given array
    int arr[] = { -1, 2, -10, 4, -20 };
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
    // Function Call
    cout << maximumSum(arr, N);
    return 0;
}
 
// this code is contributed by bhardwajji




import java.util.Arrays;
 
class Main {
    // Function to find the maximum sum of the subsequence
    // formed
    static int maximumSum(int a[], int n)
    {
        // initialize Dp to store computation of subproblems
        int[][] dp = new int[n + 1][n + 2];
        for (int[] row : dp) {
            Arrays.fill(row, 0);
        }
 
        // Traverse the array in reverse order and fill the
        // dp table
        for (int i = n - 1; i >= 0; i--) {
            for (int j = 1; j <= n + 1; j++) {
                // check if the indices are within bounds
                if (i + 1 < n && j + 1 < n + 2) {
                    // Include the current element
                    int ans1 = dp[i + 1][j + 1] + a[i] * j;
                    // Exclude the current element
                    int ans2 = dp[i + 1][j];
                    // Update the maximum ans
                    dp[i][j] = Math.max(ans1, ans2);
                }
            }
        }
 
        // Return the answer
        return dp[0][1];
    }
 
    public static void main(String[] args)
    {
        // Given array
        int[] arr = { -1, 2, -10, 4, -20 };
        // Size of the array
        int N = arr.length;
        // Function Call
        System.out.println(maximumSum(arr, N));
    }
}




def maximumSum(a, n):
   
    # initialize dp to store computation of subproblems
    dp = [[0] * (n+2) for _ in range(n+1)]
     
    # Traverse the array in reverse order and fill the dp table
    for i in range(n-1, -1, -1):
        for j in range(1, n+2):
           
            # check if the indices are within bounds
            if i+1 < n and j+1 < n+2:
               
                # Include the current element
                ans1 = dp[i+1][j+1] + a[i] * j
                 
                # Exclude the current element
                ans2 = dp[i+1][j]
                 
                # Update the maximum ans
                dp[i][j] = max(ans1, ans2)
     
    # Return the answer
    return dp[0][1]
 
# Given array
arr = [-1, 2, -10, 4, -20]
# Size of the array
N = len(arr)
 
# Function call
print(maximumSum(arr, N))




using System;
 
class MainClass {
    // Function to find the maximum sum of the subsequence
    // formed
    static int maximumSum(int[] a, int n)
    {
        // initialize Dp to store computation of subproblems
        int[][] dp = new int[n + 1][];
        for (int i = 0; i < dp.Length; i++) {
            dp[i] = new int[n + 2];
            for (int j = 0; j < dp[i].Length; j++) {
                dp[i][j] = 0;
            }
        }
 
        // Traverse the array in reverse order and fill the
        // dp table
        for (int i = n - 1; i >= 0; i--) {
            for (int j = 1; j <= n + 1; j++) {
                // check if the indices are within bounds
                if (i + 1 < n && j + 1 < n + 2) {
                    // Include the current element
                    int ans1 = dp[i + 1][j + 1] + a[i] * j;
                    // Exclude the current element
                    int ans2 = dp[i + 1][j];
                    // Update the maximum ans
                    dp[i][j] = Math.Max(ans1, ans2);
                }
            }
        }
 
        // Return the answer
        return dp[0][1];
    }
 
    public static void Main(string[] args)
    {
        // Given array
        int[] arr = { -1, 2, -10, 4, -20 };
        // Size of the array
        int N = arr.Length;
        // Function Call
        Console.WriteLine(maximumSum(arr, N));
    }
}




// JavaScript program for above approach
 
// Function to find the maximum
// sum of the subsequence formed
function maximumSum(a, n)
{  
    // initialize Dp to store computation of subproblems
    let dp = new Array(n+1).fill(0).map(() => new Array(n+2).fill(0));
 
    // Traverse the array in reverse order and fill the dp table
    for(let i=n-1; i>=0; i--)
    {
        for(let j=1; j<=n+1; j++)
        {
            // Include the current element
            let ans1 = dp[i+1][j+1] + a[i]*j;
             
            // Exclude the current element
            let ans2 = dp[i+1][j];
             
            // Update the maximum ans
            dp[i][j] = Math.max(ans1, ans2);
        }
    }
     
    // Return the answer
    return dp[0][1];
}
 
// Given array
let arr = [ -1, 2, -10, 4, -20 ];
 
// Size of the array
let N = arr.length;
 
// Function Call
console.log(maximumSum(arr, N));

Output

15

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


Article Tags :