Related Articles

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

• Difficulty Level : Expert
• Last Updated : 10 Oct, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: A[] = {1, 2, 3, 4}
Output: 12
Explanation:
In the first operation, select i = 2. The score will be increased by A * A = 2 * 4 = 8. The new array after removing A will be  {1, 2, 4}.
In the first operation, select i = 1. The score will be increased by A * A = 1 * 4 = 4. The new array after removing A 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[N-1].

Below is the implementation of the above approach:

## C++

 `// C++ implementation for the above approach``#include ``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;` `// 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[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``    ``# len1gths 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 len1gth 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

 ``

Output:
```12
0```

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

My Personal Notes arrow_drop_up