Open In App

Maximize sum of product of neighbouring elements of the element removed from Array

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A[] of size N, the task is to find the maximum score possible of this array. The score of an array is calculated by performing the following operations on the array until the size of the array is greater than 2:

  • Select an index i such that  1 < i < N.
  • Add A[i-1] * A[i+1] into the score
  • Remove A[i] from the array.

Example:

Input: A[] = {1, 2, 3, 4}
Output: 12
Explanation:
In the first operation, select i = 2. The score will be increased by A[1] * A[3] = 2 * 4 = 8. The new array after removing A[2] will be  {1, 2, 4}.
In the first operation, select i = 1. The score will be increased by A[0] * A[2] = 1 * 4 = 4. The new array after removing A[2] will be  {1, 4}.
Since N <= 2, no more operations are possible. 
The total score will be 8 + 4 = 12 which is the maximum over all possible choices.

Input: {1, 55}
Output: 0
Explanation: No valid moves are possible.

Approach: The given problem can be solved using Dynamic Programming based on the following observations:

  • Consider a 2D array, say dp[][] where dp[i][j] represents the maximum possible score in the subarray from index i to j.
  • Iterate over all the subarrays of lengths len in the range [1, N-1] in increasing order where i denotes the start and j denoted the ending index of the subarray of current length.
  • It can be observed that for a subarray from i to j, the index of the last remaining element k, other than i and j can be in the range [i+1, j-1]. Therefore, iterate over all possible values of k. Therefore, the DP relation can be stated as follows:

dp[i][j]  = max( dp[i][j], dp[i][k] + dp[k][j] + A[i]*A[j])  for all k in range [i+1, j-1]

  • The final answer will be dp[0][N-1].

Below is the implementation of the above approach: 

C++




// C++ implementation for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Stores the dp state where dp[i][j]
// represents the maximum possible score
// in the subarray from index i to j
int dp[101][101];
 
// Function to calculate maximum possible
// score using the given operations
int maxMergingScore(int A[], int N)
{
    // Iterate through all possible
    // lengths of the subarray
    for (int len = 1; len < N; ++len) {
 
        // Iterate through all the
        // possible starting indices i
        // having length len
        for (int i = 0; i + len < N; ++i) {
 
            // Stores the rightmost index
            // of the current subarray
            int j = i + len;
 
            // Initial dp[i][j] will be 0.
            dp[i][j] = 0;
 
            // Iterate through all possible
            // values of k in range [i+1, j-1]
            for (int k = i + 1; k < j; ++k) {
                dp[i][j] = max(
                    dp[i][j],
                    dp[i][k] + dp[k][j]
                        + A[i] * A[j]);
            }
        }
    }
 
    // Return the answer
    return dp[0][N - 1];
}
 
// Driver Code
int main()
{
    int N = 4;
    int A[] = { 1, 2, 3, 4 };
 
    // Function Call
    cout << maxMergingScore(A, N) << endl;
 
    N = 2;
    int B[] = { 1, 55 };
 
    // Function Call
    cout << maxMergingScore(B, N) << endl;
 
    return 0;
}


Java




// Java program for the above approach
import java.io.*;
class GFG
{
 
  // Stores the dp state where dp[i][j]
  // represents the maximum possible score
  // in the subarray from index i to j
  static int maxMergingScore(int A[], int N)
  {
    int[][] dp = new int[101][101];
    for(int i = 0; i < 101; i++)
    {
      {
        for(int j = 0; j < 101; j++)
          dp[i][j] = 0;
      }
    }
 
    // Iterate through all possible
    // lengths of the subarray
    for (int len = 1; len < N; ++len) {
 
      // Iterate through all the
      // possible starting indices i
      // having length len
      for (int i = 0; i + len < N; ++i) {
 
        // Stores the rightmost index
        // of the current subarray
        int j = i + len;
 
        // Initial dp[i][j] will be 0.
        dp[i][j] = 0;
 
        // Iterate through all possible
        // values of k in range [i+1, j-1]
        for (int k = i + 1; k < j; ++k) {
          dp[i][j] = Math.max(
            dp[i][j],
            dp[i][k] + dp[k][j]
            + A[i] * A[j]);
        }
      }
    }
 
    // Return the answer
    return dp[0][N - 1];
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int N = 4;
    int A[] = { 1, 2, 3, 4 };
 
    // Function Call
    System.out.println(maxMergingScore(A, N) );
 
    N = 2;
    int B[] = { 1, 55 };
 
    // Function Call
    System.out.println(maxMergingScore(B, N) );
  }
}
 
// This code is contributed by dwivediyash


C#




// C# program for the above approach
using System;
 
public class GFG
{
 
  // Stores the dp state where dp[i][j]
  // represents the maximum possible score
  // in the subarray from index i to j
  static int maxMergingScore(int []A, int N)
  {
    int[,] dp = new int[101,101];
    for(int i = 0; i < 101; i++)
    {
      {
        for(int j = 0; j < 101; j++)
          dp[i, j] = 0;
      }
    }
 
    // Iterate through all possible
    // lengths of the subarray
    for (int len = 1; len < N; ++len) {
 
      // Iterate through all the
      // possible starting indices i
      // having length len
      for (int i = 0; i + len < N; ++i) {
 
        // Stores the rightmost index
        // of the current subarray
        int j = i + len;
 
        // Initial dp[i][j] will be 0.
        dp[i,j] = 0;
 
        // Iterate through all possible
        // values of k in range [i+1, j-1]
        for (int k = i + 1; k < j; ++k) {
          dp[i,j] = Math.Max(
            dp[i,j],
            dp[i,k] + dp[k,j]
            + A[i] * A[j]);
        }
      }
    }
 
    // Return the answer
    return dp[0,N - 1];
  }
 
  // Driver Code
    static public void Main (){
 
    int N = 4;
    int []A = { 1, 2, 3, 4 };
 
    // Function Call
    Console.WriteLine(maxMergingScore(A, N) );
 
    N = 2;
    int[] B = { 1, 55 };
 
    // Function Call
    Console.WriteLine(maxMergingScore(B, N) );
    }
}
 
// This code is contributed by maddler.


Python3




# Python 3 implementation for the above approach
 
# Stores the dp state where dp[i][j]
# represents the maximum possible score
# in the subarray from index i to j
 
# Function to calculate maximum possible
# score using the given operations
def maxMergingScore(A, N):
   
    # Iterate through all possible
    # lengths of the subarray
    dp = [[0 for i in range(101)] for j in range(101)]
    for len1 in range(1,N,1):
       
        # Iterate through all the
        # possible starting indices i
        # having length len1
        for i in range(0, N - len1, 1):
           
            # Stores the rightmost index
            # of the current subarray
            j = i + len1
 
            # Initial dp[i][j] will be 0.
            dp[i][j] = 0
 
            # Iterate through all possible
            # values of k in range [i+1, j-1]
            for k in range(i + 1, j, 1):
                dp[i][j] = max(dp[i][j],dp[i][k] + dp[k][j] + A[i] * A[j])
 
    # Return the answer
    return dp[0][N - 1]
 
# Driver Code
if __name__ == '__main__':
    N = 4
    A = [1, 2, 3, 4]
 
    # Function Call
    print(maxMergingScore(A, N))
 
    N = 2
    B = [1, 55]
 
    # Function Call
    print(maxMergingScore(B, N))
     
    # This code is contributed by SURENDRA_GANGWAR.


Javascript




<script>
        // JavaScript Program to implement
        // the above approach
 
        // Stores the dp state where dp[i][j]
        // represents the maximum possible score
        // in the subarray from index i to j
        let dp = Array(101).fill().map(() => Array(101));
 
        // Function to calculate maximum possible
        // score using the given operations
        function maxMergingScore(A, N)
        {
         
            // Iterate through all possible
            // lengths of the subarray
            for (let len = 1; len < N; ++len) {
 
                // Iterate through all the
                // possible starting indices i
                // having length len
                for (let i = 0; i + len < N; ++i) {
 
                    // Stores the rightmost index
                    // of the current subarray
                    let j = i + len;
 
                    // Initial dp[i][j] will be 0.
                    dp[i][j] = 0;
 
                    // Iterate through all possible
                    // values of k in range [i+1, j-1]
                    for (let k = i + 1; k < j; ++k) {
                        dp[i][j] = Math.max(
                            dp[i][j],
                            dp[i][k] + dp[k][j]
                            + A[i] * A[j]);
                    }
                }
            }
 
            // Return the answer
            return dp[0][N - 1];
        }
 
        // Driver Code
        let N = 4;
        let A = [1, 2, 3, 4];
 
        // Function Call
        document.write(maxMergingScore(A, N) + "<br>");
 
        N = 2;
        let B = [1, 55];
 
        // Function Call
        document.write(maxMergingScore(B, N) + "<br>");
 
// This code is contributed by Potta Lokesh
    </script>


 
 

Output: 

12
0

 

 

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

 



Last Updated : 04 Aug, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads