MaxSkill: Optimally Removing People to Maximise Skill

Last Updated : 11 Jul, 2025

Given a queue of n people, indexed from 0 to n - 1. Each person has a rating represented by an array arr[], where arr[i] represents the rating of the i-th person. The skill of a person depends not only on their rating but also on their immediate neighbours.

If you remove the i-th person from the queue, you gain a skill value of arr[i - 1] * arr[i] * arr[i + 1]. If i - 1 or i + 1 is out of bounds, assume there is an implicit person with a rating of 1 at that position.

Your task is to remove all n people one by one in an optimal order to maximize the total skill value. After removing a person, the remaining queue should be rearranged in their original order before the next removal.

Return the maximum total skill you can obtain by removing the people optimally.

Examples :

Input: arr[] = [5, 10]
Output: 60
Explanation:

  • Remove person with rating 5 → Skill gained = 1 * 5 * 10 = 50, remaining queue: [10].
  • Remove person with rating 10 → Skill gained = 1 * 10 * 1 = 10, total skill = 50 + 10 = 60.

Input: arr[] = [3, 2, 5, 8]
Output: 182
Explanation:

  • Remove person with rating 2 → Skill gained = 3 * 2 * 5 = 30, remaining queue: [3, 5, 8].
  • Remove person with rating 5 → Skill gained = 3 * 5 * 8 = 120, remaining queue: [3, 8].
  • Remove person with rating 3 → Skill gained = 1 * 3 * 8 = 24, remaining queue: [8].
  • Remove person with rating 8 → Skill gained = 1 * 8 * 1 = 8, total skill = 30 + 120 + 24 + 8 = 182
Try It Yourself
redirect icon

[Naive Approach] Using Recursion

To solve the problem using recursion, let's consider a recursive approach by focusing on each person removal individually and calculating the maximum skill at each step.

To maximize the total skill value, we can choose a person i to remove last in a given range [left, right]. The skill from removing i last is given by: arr[left-1]*arr[i]*arr[right+1] plus the maximum skill from the left subarray [left, i-1] and right subarray [i+1, right].

This gives the recurrence relation:

  • maxSkill(l, r) = max(arr[l-1] * arr[i] * arr[r+1] + maxSkill(l, i-1) + maxSkill(i+1, r))
C++
// C++ code to get maximum skill value 
// by removing people using recursion.

#include <bits/stdc++.h>
using namespace std;

// Recursive function to calculate maximum 
// skill from removing people in range [left, right]
int getMaxSkill(int left, int right, vector<int> &arr) {
  
  	// No people in this range
    if (left > right) return 0; 

    int maxSkill = 0;

    // Try each person `k` in range [left, right] 
  	// as the last person to remove
    for (int k = left; k <= right; k++) {
      	
        // Calculate skill from removing `k` 
      	// last in this range
        int skill = arr[left - 1] * arr[k] * arr[right + 1];

        // Recursively compute skill from the left and 
      	// right subarrays
        int leftSkill = getMaxSkill(left, k - 1, arr);
        int rightSkill = getMaxSkill(k + 1, right, arr);

        // Update maxSkill with the best option
        maxSkill = max(maxSkill, skill + leftSkill + rightSkill);
    }
    
    return maxSkill;
}

// Function to calculate the maximum skill
// obtainable by removing all people
int maxSkill(vector<int> &arr) {
  
  	int n = arr.size();
  
    // Add virtual people with rating 
  	// 1 at both ends of `arr`
    arr.insert(arr.begin(), 1);
    arr.push_back(1);

    // Call recursive helper on the 
  	// full range of people
    return getMaxSkill(1, n, arr);
}

int main() {
  
    vector<int> arr = {3, 2, 5, 8};
    cout << maxSkill(arr);
    return 0;
}
Java
// Java code to get maximum skill value 
// by removing people using recursion.
import java.util.*;

class GfG {

    // Recursive function to calculate maximum skill 
    // from removing people in range [left, right]
    static int getMaxSkill(int left, int right, int[] arr) {

        // No people in this range
        if (left > right)
            return 0;

        int maxSkill = 0;

        // Try each person `k` in range [left, right] 
        // as the last person to remove
        for (int k = left; k <= right; k++) {

            // Calculate skill from removing `k` last in
            // this range
            int skill = arr[left - 1] * arr[k] * arr[right + 1];

            // Recursively compute skill from the left and
            // right subarrays
            int leftSkill = getMaxSkill(left, k - 1, arr);
            int rightSkill = getMaxSkill(k + 1, right, arr);

            // Update maxSkill with the best option
            maxSkill = Math.max(maxSkill, skill + leftSkill + rightSkill);
        }

        return maxSkill;
    }

    // Function to calculate the maximum skill obtainable 
    // by removing all people
    static int maxSkill(int[] arr) {
      
        int n = arr.length;

        // Create a new array to store the original array
        // plus virtual people at the ends
        int[] nums = new int[n + 2];

        // Add virtual people with rating 1 
        // at both ends of `nums`
        nums[0] = 1;
        nums[n + 1] = 1;

        // Copy the elements of the original array into the
        // new array
        for (int i = 0; i < n; i++) {
            nums[i + 1] = arr[i];
        }

        // Call recursive helper on the full range of
        // people
        return getMaxSkill(1, n, nums);
    }

    public static void main(String[] args) {
      
        int[] arr = { 3, 2, 5, 8 };
        System.out.println(maxSkill(arr));
    }
}
Python
# Python code to get maximum skill value 
# by removing people using recursion.

# Recursive function to calculate maximum skill 
# from removing people in range [left, right]
def getMaxSkill(left, right, arr):
  
    # No people in this range
    if left > right:
        return 0

    maxSkill = 0

    # Try each person `k` in range [left, right] 
    # as the last person to remove
    for k in range(left, right + 1):
      
        # Calculate skill from removing `k` last in this range
        skill = arr[left - 1] * arr[k] * arr[right + 1]

        # Recursively compute skill from the left and
        # right subarrays
        leftSkill = getMaxSkill(left, k - 1, arr)
        rightSkill = getMaxSkill(k + 1, right, arr)

        # Update maxSkill with the best option
        maxSkill = max(maxSkill, skill + leftSkill + rightSkill)

    return maxSkill

# Function to calculate the maximum skill
# obtainable by removing all people
def maxSkill(arr):
  
    # Add virtual people with rating 1 at both
    # ends of `arr`
    n = len(arr)
    arr = [1] + arr + [1]

    # Call recursive helper on the full 
    # range of people
    return getMaxSkill(1, n, arr)

if __name__ == "__main__":
    arr = [3, 2, 5, 8]
    print(maxSkill(arr))
C#
// C# code to get maximum skill value 
// by removing people using recursion.
using System;
using System.Collections.Generic;

class GfG {
  
    // Recursive function to calculate maximum skill 
    // from removing people in range [left, right]
    static int getMaxSkill(int left, int right, List<int> arr) {
      
        // No people in this range
        if (left > right) return 0;

        int maxSkill = 0;

        // Try each person `k` in range [left, right] 
        // as the last person to remove
        for (int k = left; k <= right; k++) {
          
            // Calculate skill from removing `k` last in this range
            int skill = arr[left - 1] * arr[k] * arr[right + 1];

            // Recursively compute skill from the left 
            // and right subarrays
            int leftSkill = getMaxSkill(left, k - 1, arr);
            int rightSkill = getMaxSkill(k + 1, right, arr);

            // Update maxSkill with the best option
            maxSkill = Math.Max(maxSkill, skill + leftSkill + rightSkill);
        }

        return maxSkill;
    }

    // Function to calculate the maximum skill
    // obtainable by removing all people
    static int maxSkill(List<int> arr) {
      
        // Add virtual people with rating 
        // 1 at both ends of `arr`
        int n = arr.Count;
        arr.Insert(0, 1);
        arr.Add(1);

        // Call recursive helper on the full range
        // of people
        return getMaxSkill(1, n, arr);
    }

    static void Main() {
      
        List<int> arr = new List<int> { 3, 2, 5, 8 };
        Console.WriteLine(maxSkill(arr));
    }
}
JavaScript
// JavaScript code to get maximum skill value 
// by removing people using recursion.

// Recursive function to calculate maximum skill
// from removing people in range [left, right]
function getMaxSkill(left, right, arr) {

    // No people in this range
    if (left > right)
        return 0;

    let maxSkill = 0;

    // Try each person `k` in range [left, right]
    // as the last person to remove
    for (let k = left; k <= right; k++) {
    
        // Calculate skill from removing `k` last in this range
        let skill = arr[left - 1] * arr[k] * arr[right + 1];

        // Recursively compute skill from the left and right
        // subarrays
        let leftSkill = getMaxSkill(left, k - 1, arr);
        let rightSkill = getMaxSkill(k + 1, right, arr);

        // Update maxSkill with the best option
        maxSkill = Math.max(maxSkill, skill + leftSkill + rightSkill);
    }

    return maxSkill;
}

// Function to calculate the maximum skill
// obtainable by removing all people
function maxSkill(arr) {

    // Add virtual people with rating 1 at both ends of `arr`
    let n = arr.length;
    arr.unshift(1);
    arr.push(1);

    // Call recursive helper on the full range of people
    return getMaxSkill(1, n, arr);
}

// Driver Code 
const arr = [3, 2, 5, 8];
console.log(maxSkill(arr));

Output
182

Time complexity: O(4n/(n3/2)), time complexity is exponential due to the recursive partitioning.
Auxiliary Space: O(n), recursive stack.

[Better Approach] Using Top-Down DP (Memoization) - O(n^3) Time and O(n^2) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming:

  1. Optimal Substructure: TThe maximum skill value obtained from removing people in a range [left, right] depends on the optimal solution of subproblems [left, k-1] and [k+1, right], where k is the last person removed in the current range. By selecting each person k as the last to remove in the current range, we can combine the results of these subproblems to determine the maximum skill achievable for the range [left, right].
  2. Overlapping Subproblems: In a purely recursive approach, the same subproblems are calculated multiple times. For example, when calculating the maximum skill for a range [1, n], the recursive calls may repeatedly calculate the maximum skill for the same subranges, such as [1, k-1] or [k+1, n]. This repetition leads to overlapping subproblems.

To avoid recomputing results for the same subproblems, we use a 2D DP array dp of size (n+2) × (n+2) (as virtual persons with a rating of 1 are also added at both ends of the arr[] to simplify the handling of boundary conditions), where dp[left][right] stores the maximum skill value obtainable from removing all people in the range [left, right].

We initialize all entries in dp to -1 and populate them using memoization as we calculate optimal subproblems.

C++
#include <bits/stdc++.h>
using namespace std;

// Recursive function to calculate maximum skill value
// from removing people in range [left, right]
// with memoization (Top-Down DP)
int getMaxSkill(int left, int right, vector<int> &arr, 
                vector<vector<int>> &memo) {
  
    // If no people in this range, return 0
    if (left > right) return 0;

    // If the result is already computed, return it
    if (memo[left][right] != -1) return memo[left][right];

    int maxSkill = 0;

    // Try each person `k` in range [left, right] 
    // as the last person to remove
    for (int k = left; k <= right; k++) {
      
        // Calculate skill value from removing `k` 
        // last in this range
        int skill = arr[left - 1] * arr[k] * arr[right + 1];

        // Recursively compute skill value from the left and 
        // right subarrays
        int leftSkill = getMaxSkill(left, k - 1, arr, memo);
        int rightSkill = getMaxSkill(k + 1, right, arr, memo);

        // Update maxSkill with the best option
        maxSkill = max(maxSkill, skill + leftSkill + rightSkill);
    }

    // Store the result in the memoization table
    memo[left][right] = maxSkill;

    return maxSkill;
}

// Function to calculate the maximum skill value
// obtainable by removing all people
int maxSkill(vector<int> &arr) {
  
  	int n = arr.size();
  
    // Add virtual persons with value 1 at 
  	// both ends of `arr`
    arr.insert(arr.begin(), 1);
    arr.push_back(1);

    // Create a memoization table initialized to -1
    vector<vector<int>> memo(n + 2, vector<int>(n + 2, -1));

    // Call the recursive helper on the full 
  	// range of people
    return getMaxSkill(1, n, arr, memo);
}

int main() {
  
    vector<int> arr = {3, 2, 5, 8};
    cout << maxSkill(arr);
    return 0;
}
Java
class GfG {

    // Recursive function to calculate maximum skill
    // from removing people in range [left, right]
    // with memoization (Top-Down DP)
    static int getMaxSkill(int left, int right, int[] arr, int[][] memo) {

        // If no people in this range, return 0
        if (left > right)
            return 0;

        // If the result is already computed, return it
        if (memo[left][right] != -1)
            return memo[left][right];

        int maxSkill = 0;

        // Try each person `k` in range [left, right] as
        // the last person to remove
        for (int k = left; k <= right; k++) {

            // Calculate skill from removing `k` last in
            // this range
            int skill = arr[left - 1] * arr[k] * arr[right + 1];

            // Recursively compute skill from the left and
            // right subarrays
            int leftSkill = getMaxSkill(left, k - 1, arr, memo);
            int rightSkill = getMaxSkill(k + 1, right, arr, memo);

            // Update maxSkill with the best option
            maxSkill = Math.max(maxSkill, skill + leftSkill + rightSkill);
        }

        // Store the result in the memoization table
        memo[left][right] = maxSkill;

        return maxSkill;
    }

    // Function to calculate the maximum skill value
    // obtainable by removing all people
    static int maxSkill(int[] arr) {

        // Add virtual people with value 1 at both ends of `arr`
        int n = arr.length;
        int[] newArr = new int[n + 2];
        newArr[0] = 1;
        for (int i = 0; i < n; i++) {
            newArr[i + 1] = arr[i];
        }
        newArr[n + 1] = 1;

        // Create a memoization table initialized to -1
        int[][] memo = new int[n + 2][n + 2];
        for (int i = 0; i < n + 2; i++) {
            for (int j = 0; j < n + 2; j++) {
                memo[i][j] = -1;
            }
        }

        // Call the recursive helper on the full range of people
        return getMaxSkill(1, n, newArr, memo);
    }

    public static void main(String[] args) {
        int[] arr = { 3, 2, 5, 8 };
        System.out.println(maxSkill(arr));
    }
}
Python
# Python code to get the maximum skill value by removing people.
# using memoization (Top-Down DP).

# Recursive function to calculate maximum skill
# from removing people in range [left, right]
# with memoization (Top-Down DP)

def getMaxSkill(left, right, arr, memo):
  
    # If no people in this range, return 0
    if left > right:
        return 0

    # If the result is already computed, return it
    if memo[left][right] != -1:
        return memo[left][right]

    maxSkill = 0

    # Try each person `k` in range [left, right]
    # as the last person to remove
    for k in range(left, right + 1):
      
        # Calculate skill from removing `k`
        # last in this range
        skill = arr[left - 1] * arr[k] * arr[right + 1]

        # Recursively compute skill from the left and
        # right subarrays
        leftSkill = getMaxSkill(left, k - 1, arr, memo)
        rightSkill = getMaxSkill(k + 1, right, arr, memo)

        # Update maxSkill with the best option
        maxSkill = max(maxSkill, skill + leftSkill + rightSkill)

    # Store the result in the memoization table
    memo[left][right] = maxSkill

    return maxSkill

# Function to calculate the maximum skill value
# obtainable by removing all people

def maxSkill(arr):
  	
    n = len(arr)
    
    # Add virtual people with value 1 at
    # both ends of `arr`
    arr = [1] + arr + [1]

    # Create a memoization table initialized to -1
    memo = [[-1 for _ in range(n + 2)] for _ in range(n + 2)]

    # Call the recursive helper on the full 
    # range of people
    return getMaxSkill(1, n, arr, memo)


if __name__ == "__main__":
    arr = [3, 2, 5, 8]
    print(maxSkill(arr))
C#
using System;

class GfG {
    // Recursive function to calculate maximum skill value
    // from removing people in range [left, right]
    // with memoization (Top-Down DP)
    static int getMaxSkill(int left, int right, int[] arr, int[,] memo) {
        // If no people in this range, return 0
        if (left > right)
            return 0;

        // If the result is already computed, return it
        if (memo[left, right] != -1)
            return memo[left, right];

        int maxSkill = 0;

        // Try each person `k` in range [left, right]
        // as the last person to remove
        for (int k = left; k <= right; k++) {
            // Calculate skill value from removing `k` last in this range
            int skill = arr[left - 1] * arr[k] * arr[right + 1];

            // Recursively compute skill value from the left and right subarrays
            int leftSkill = getMaxSkill(left, k - 1, arr, memo);
            int rightSkill = getMaxSkill(k + 1, right, arr, memo);

            // Update maxSkill with the best option
            maxSkill = Math.Max(maxSkill, skill + leftSkill + rightSkill);
        }

        // Store the result in the memoization table
        memo[left, right] = maxSkill;

        return maxSkill;
    }

    // Function to calculate the maximum skill value
    // obtainable by removing all people
    static int maxSkill(int[] arr) {
        int n = arr.Length;

        // Add virtual persons with value 1 at both ends of `arr`
        int[] newArr = new int[n + 2];
        newArr[0] = 1;
        for (int i = 0; i < n; i++)
        {
            newArr[i + 1] = arr[i];
        }
        newArr[n + 1] = 1;

        // Create a memoization table initialized to -1
        int[,] memo = new int[n + 2, n + 2];
        for (int i = 0; i < n + 2; i++)
        {
            for (int j = 0; j < n + 2; j++)
            {
                memo[i, j] = -1;
            }
        }

        // Call the recursive helper on the full range of people
        return getMaxSkill(1, n, newArr, memo);
    }

    static void Main() {
        int[] arr = { 3, 2, 5, 8 };
        Console.WriteLine(maxSkill(arr));
    }
}
JavaScript
// JavaScript code to get the maximum skill value 
// by removing people using memoization.

function getMaxSkill(left, right, arr, memo) {
    // If no people in this range, return 0
    if (left > right)
        return 0;

    // If the result is already computed, return it
    if (memo[left][right] !== -1)
        return memo[left][right];

    let maxSkill = 0;

    // Try each person `k` in range [left, right]
    // as the last person to remove
    for (let k = left; k <= right; k++) {
    
        // Calculate skill value from removing `k` last in this range
        let skill = arr[left - 1] * arr[k] * arr[right + 1];

        // Recursively compute skill value from the left and right subarrays
        let leftSkill = getMaxSkill(left, k - 1, arr, memo);
        let rightSkill = getMaxSkill(k + 1, right, arr, memo);

        // Update maxSkill with the best option
        maxSkill = Math.max(maxSkill, skill + leftSkill + rightSkill);
    }

    // Store the result in the memoization table
    memo[left][right] = maxSkill;

    return maxSkill;
}

// Function to calculate the maximum skill value
// obtainable by removing all people
function maxSkill(arr) {
    let n = arr.length;

    // Add virtual persons with value 1 at both ends of `arr`
    arr = [1, ...arr, 1];

    // Create a memoization table initialized to -1
    let memo = Array.from({ length: n + 2 }, () => Array(n + 2).fill(-1));

    // Call the recursive helper on the full range of people
    return getMaxSkill(1, n, arr, memo);
}

// Driver Code 
let arr = [3, 2, 5, 8];
console.log(maxSkill(arr));

Output
182

[Expected Approach] Using Bottom-Up DP (Tabulation) - O(n^3) Time and O(n^2) Space

The approach is similar to the previous one. However, instead of breaking down the problem recursively, we iteratively build up the solution by calculating it in a bottom-up manner.

We maintain a dp[][] table such that dp[i][j] stores the maximum skill value that can be obtained by removing all the people between index i and j, inclusive.

This eliminates the need for recursion and avoids redundant computations, making the solution more efficient. The bottom-up dynamic programming (DP) approach ensures that smaller subproblems are solved first, and their results are used to construct solutions for larger subarrays

C++
// C++ program to find the maximum skill by removing
// people using tabulation (bottom-up dynamic programming):

#include <bits/stdc++.h>
using namespace std;

// Function to calculate maximum skill value
// from removing people in range [left, right]
int maxSkill(vector<int> &arr) {
    
  	int n = arr.size();

    // Add virtual people with skill value 1 at both
  	// ends of `arr`
    arr.insert(arr.begin(), 1);
    arr.push_back(1);

    // Initialize the dp table with 0
    vector<vector<int>> dp(n + 2, vector<int>(n + 2, 0));

    // Iterate over subarrays of increasing length
    for (int length = 1; length <= n; length++) {
        for (int left = 1; left <= n - length + 1; left++) {
            int right = left + length - 1;

            // Try every possible last person to remove
            for (int k = left; k <= right; k++) {
              
                // Calculate skill from removing `k` 
              	// last in this range
                int skill = arr[left - 1] * arr[k] * arr[right + 1];

                // Add skill from the left and right 
              	// subarrays
                int totalSkill = skill + dp[left][k - 1] + dp[k + 1][right];

                // Update dp[left][right] with the maximum skill
                dp[left][right] = max(dp[left][right], totalSkill);
            }
        }
    }

    // Return the result from the dp table for
    // the full range of people
    return dp[1][n];
}

int main() {
  
    vector<int> arr = {3, 2, 5, 8};
    cout << maxSkill(arr);
    return 0;
}
Java
// Java program to find the maximum skill by removing
// people using tabulation (bottom-up dynamic programming):

class GfG {

    // Function to calculate maximum skill value
    // from removing people in range [left, right]
    static int maxSkill(int[] arr) {
      
        int n = arr.length;

        // Add virtual people with skill value 1 at both ends
        int[] nums = new int[n + 2];
        nums[0] = 1;
        nums[n + 1] = 1;
        for (int i = 0; i < n; i++) {
            nums[i + 1] = arr[i];
        }

        // Initialize the dp table with 0
        int[][] dp = new int[n + 2][n + 2];

        // Iterate over subarrays of increasing length
        for (int length = 1; length <= n; length++) {
            for (int left = 1; left <= n - length + 1; left++) {
                int right = left + length - 1;

                // Try every possible last person to remove
                for (int k = left; k <= right; k++) {
                  
                    // Calculate skill from removing `k` last in this range
                    int skill = nums[left - 1] * nums[k] * nums[right + 1];

                    // Add skill from the left and right subarrays
                    int totalSkill = skill + dp[left][k - 1] + dp[k + 1][right];

                    // Update dp[left][right] with the maximum skill
                    dp[left][right] = Math.max(dp[left][right], totalSkill);
                }
            }
        }

        // Return the result from the dp table for the full range of people
        return dp[1][n];
    }

    public static void main(String[] args) {
      
        int[] arr = { 3, 2, 5, 8 };
        System.out.println(maxSkill(arr));
    }
}
Python
# Python program to find the maximum skill by removing
# people using tabulation (bottom-up dynamic programming):

# Function to calculate maximum skill value
# from removing people in range [left, right]
def maxSkill(arr):
  
    n = len(arr)

    # Add virtual people with skill value 1 at both ends
    arr = [1] + arr + [1]

    # Initialize the dp table with 0
    dp = [[0] * (n + 2) for _ in range(n + 2)]

    # Iterate over subarrays of increasing length
    for length in range(1, n + 1):
        for left in range(1, n - length + 2):
            right = left + length - 1

            # Try every possible last person to remove
            for k in range(left, right + 1):
              
                # Calculate skill from removing `k` last in this range
                skill = arr[left - 1] * arr[k] * arr[right + 1]

                # Add skill from the left and right subarrays
                totalSkill = skill + dp[left][k - 1] + dp[k + 1][right]

                # Update dp[left][right] with the maximum skill
                dp[left][right] = max(dp[left][right], totalSkill)

    # Return the result from the dp table for the 
    # full range of people
    return dp[1][n]

if __name__ == "__main__":
    arr = [3, 2, 5, 8]
    print(maxSkill(arr))
C#
// C# program to find the maximum skill by removing
// people using tabulation (bottom-up dynamic programming):

using System;

class GfG {
  
    // Function to calculate maximum skill value
    // from removing people in range [left, right]
    static int maxSkill(int[] arr) {
      
        // Add virtual people with skill value 1 at both ends
        int n = arr.Length;
        int[] skills = new int[n + 2];
        skills[0] = 1;
        skills[n + 1] = 1;
        for (int i = 0; i < n; i++) {
            skills[i + 1] = arr[i];
        }

        // Initialize the dp table with 0
        int[,] dp = new int[n + 2, n + 2];

        // Iterate over subarrays of increasing length
        for (int length = 1; length <= n; length++) {
            for (int left = 1; left <= n - length + 1; left++) {
                int right = left + length - 1;

                // Try every possible last person to remove
                for (int k = left; k <= right; k++) {
                  
                    // Calculate skill from removing `k`
                    // last in this range
                    int skill = skills[left - 1] * 
                    skills[k] * skills[right + 1];

                    // Add skill from the left and right subarrays
                    int totalSkill = skill + 
                    dp[left, k - 1] + dp[k + 1, right];

                    // Update dp[left, right] with the maximum skill
                    dp[left, right] = Math.Max(dp[left, right], totalSkill);
                }
            }
        }

        // Return the result from the dp table 
        // for the full range of people
        return dp[1, n];
    }

    static void Main() {
      
        int[] arr = { 3, 2, 5, 8 };
        Console.WriteLine(maxSkill(arr));
    }
}
JavaScript
// JavaScript program to find the maximum skill by removing
// people using tabulation (bottom-up dynamic programming):

function maxSkill(arr) {
    let n = arr.length;

    // Add virtual people with skill value 1 at both ends
    arr = [1, ...arr, 1];

    // Initialize the dp table with 0
    let dp = Array.from({ length: n + 2 }, () => Array(n + 2).fill(0));

    // Iterate over subarrays of increasing length
    for (let length = 1; length <= n; length++) {
        for (let left = 1; left <= n - length + 1; left++) {
            let right = left + length - 1;

            // Try every possible last person to remove
            for (let k = left; k <= right; k++) {
                // Calculate skill from removing `k` last in this range
                let skill = arr[left - 1] * arr[k] * arr[right + 1];

                // Add skill from the left and right subarrays
                let totalSkill = skill + dp[left][k - 1] + dp[k + 1][right];

                // Update dp[left][right] with the maximum skill
                dp[left][right] = Math.max(dp[left][right], totalSkill);
            }
        }
    }

    // Return the result from the dp table for the full range of people
    return dp[1][n];
}

// Driver Code 
const arr = [3, 2, 5, 8];
console.log(maxSkill(arr));

Output
182
Comment