Maximize cost to empty an array by removing contiguous subarrays of equal elements
Given an array arr[] consisting of N integers and an integer M, the task is to find the maximum cost that can be obtained by performing the following operation any number of times.
In one operation, choose K contiguous elements with same value(where K ≥ 1) and remove them and cost of this operation is K * M.
Examples:
Input: arr[] = {1, 3, 2, 2, 2, 3, 4, 3, 1}, M = 3
Output: 27
Explanation:
Step 1: Remove three contiguous 2’s to modify arr[] = {1, 3, 3, 4, 3, 1}. Cost = 3 * 3 = 9
Step 2: Remove 4 to modify arr[] = {1, 3, 3, 3, 1}. Cost = 9 + 1 * 3 = 12
Step 3: Remove three contiguous 3’s to modify arr[] = {1, 1}. Cost = 12 + 3 * 3 = 21
Step 4: Remove two contiguous 1’s to modify arr[] = {}. Cost = 21 + 2 * 3 = 27Input: arr[] = {1, 2, 3, 4, 5, 6, 7}, M = 2
Output: 14
Approach: This problem can be solved using Dynamic Programming. Below are the steps:
- Initialize a 3D array dp[][][] such that dp[left][right][count], where left and right denotes operation between indices [left, right] and count is the number of elements to the left of arr[left] having same value as that of arr[left] and the count excludes arr[left].
- Now there are the following two possible choices:
- Ending the sequence to remove the elements of the same value including the starting element (i.e., arr[left]) and then continue from the next element onward.
- Continue the sequence to search between the indices [left + 1, right] for elements having the same value as arr[left](say index i), this enables us to continue the sequence.
- Make recursive calls from the new sequence and continue the process for the previous sequence.
- Print the maximum cost after all the above steps.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Initialize dp array int dp[101][101][101]; // Function that removes elements // from array to maximize the cost int helper( int arr[], int left, int right, int count, int m) { // Base case if (left > right) return 0; // Check if an answer is stored if (dp[left][right][count] != -1) { return dp[left][right][count]; } // Deleting count + 1 i.e. including // the first element and starting a // new sequence int ans = (count + 1) * m + helper(arr, left + 1, right, 0, m); for ( int i = left + 1; i <= right; ++i) { if (arr[i] == arr[left]) { // Removing [left + 1, i - 1] // elements to continue with // previous sequence ans = max( ans, helper(arr, left + 1, i - 1, 0, m) + helper(arr, i, right, count + 1, m)); } } // Store the result dp[left][right][count] = ans; // Return answer return ans; } // Function to remove the elements int maxPoints( int arr[], int n, int m) { int len = n; memset (dp, -1, sizeof (dp)); // Function Call return helper(arr, 0, len - 1, 0, m); } // Driver Code int main() { // Given array int arr[] = { 1, 3, 2, 2, 2, 3, 4, 3, 1 }; int M = 3; int N = sizeof (arr) / sizeof (arr[0]); // Function Call cout << maxPoints(arr, N, M); return 0; } |
Java
// Java program for the above approach import java.util.*; class GFG{ // Initialize dp array static int [][][]dp = new int [ 101 ][ 101 ][ 101 ]; // Function that removes elements // from array to maximize the cost static int helper( int arr[], int left, int right, int count, int m) { // Base case if (left > right) return 0 ; // Check if an answer is stored if (dp[left][right][count] != - 1 ) { return dp[left][right][count]; } // Deleting count + 1 i.e. including // the first element and starting a // new sequence int ans = (count + 1 ) * m + helper(arr, left + 1 , right, 0 , m); for ( int i = left + 1 ; i <= right; ++i) { if (arr[i] == arr[left]) { // Removing [left + 1, i - 1] // elements to continue with // previous sequence ans = Math.max(ans, helper(arr, left + 1 , i - 1 , 0 , m) + helper(arr, i, right, count + 1 , m)); } } // Store the result dp[left][right][count] = ans; // Return answer return ans; } // Function to remove the elements static int maxPoints( int arr[], int n, int m) { int len = n; for ( int i = 0 ; i < 101 ; i++) { for ( int j = 0 ; j < 101 ; j++) { for ( int k = 0 ; k < 101 ; k++) dp[i][j][k] = - 1 ; } } // Function call return helper(arr, 0 , len - 1 , 0 , m); } // Driver Code public static void main(String[] args) { // Given array int arr[] = { 1 , 3 , 2 , 2 , 2 , 3 , 4 , 3 , 1 }; int M = 3 ; int N = arr.length; // Function call System.out.print(maxPoints(arr, N, M)); } } // This code is contributed by Amit Katiyar |
Python3
# Python3 program for # the above approach # Initialize dp array dp = [[[ - 1 for x in range ( 101 )] for y in range ( 101 )] for z in range ( 101 )] # Function that removes elements # from array to maximize the cost def helper(arr, left, right, count, m): # Base case if (left > right): return 0 # Check if an answer is stored if (dp[left][right][count] ! = - 1 ): return dp[left][right][count] # Deleting count + 1 i.e. including # the first element and starting a # new sequence ans = ((count + 1 ) * m + helper(arr, left + 1 , right, 0 , m)) for i in range (left + 1 , right + 1 ): if (arr[i] = = arr[left]): # Removing [left + 1, i - 1] # elements to continue with # previous sequence ans = ( max (ans, helper(arr, left + 1 , i - 1 , 0 , m) + helper(arr, i, right, count + 1 , m))) # Store the result dp[left][right][count] = ans # Return answer return ans # Function to remove the elements def maxPoints(arr, n, m): length = n global dp # Function Call return helper(arr, 0 , length - 1 , 0 , m) # Driver Code if __name__ = = "__main__" : # Given array arr = [ 1 , 3 , 2 , 2 , 2 , 3 , 4 , 3 , 1 ] M = 3 N = len (arr) # Function Call print (maxPoints(arr, N, M)) # This code is contributed by Chitranayal |
C#
// C# program for the above approach using System; class GFG{ // Initialize dp array static int [,,]dp = new int [101, 101, 101]; // Function that removes elements // from array to maximize the cost static int helper( int []arr, int left, int right, int count, int m) { // Base case if (left > right) return 0; // Check if an answer is stored if (dp[left, right, count] != -1) { return dp[left, right, count]; } // Deleting count + 1 i.e. including // the first element and starting a // new sequence int ans = (count + 1) * m + helper(arr, left + 1, right, 0, m); for ( int i = left + 1; i <= right; ++i) { if (arr[i] == arr[left]) { // Removing [left + 1, i - 1] // elements to continue with // previous sequence ans = Math.Max(ans, helper(arr, left + 1, i - 1, 0, m) + helper(arr, i, right, count + 1, m)); } } // Store the result dp[left, right, count] = ans; // Return answer return ans; } // Function to remove the elements static int maxPoints( int []arr, int n, int m) { int len = n; for ( int i = 0; i < 101; i++) { for ( int j = 0; j < 101; j++) { for ( int k = 0; k < 101; k++) dp[i, j, k] = -1; } } // Function call return helper(arr, 0, len - 1, 0, m); } // Driver Code public static void Main(String[] args) { // Given array int []arr = { 1, 3, 2, 2, 2, 3, 4, 3, 1 }; int M = 3; int N = arr.Length; // Function call Console.Write(maxPoints(arr, N, M)); } } // This code is contributed by Amit Katiyar |
Javascript
<script> // Javascript program for the above approach // Initialize dp array let dp = new Array(101); for (let i = 0; i < 101; i++) { dp[i] = new Array(101); for (let j = 0; j < 101; j++) { dp[i][j] = new Array(101); for (let k = 0; k < 101; k++) { dp[i][j][k] = -1; } } } // Function that removes elements // from array to maximize the cost function helper(arr, left, right, count, m) { // Base case if (left > right) return 0; // Check if an answer is stored if (dp[left][right][count] != -1) { return dp[left][right][count]; } // Deleting count + 1 i.e. including // the first element and starting a // new sequence let ans = (count + 1) * m + helper(arr, left + 1, right, 0, m); for (let i = left + 1; i <= right; ++i) { if (arr[i] == arr[left]) { // Removing [left + 1, i - 1] // elements to continue with // previous sequence ans = Math.max(ans, helper(arr, left + 1, i - 1, 0, m) + helper(arr, i, right, count + 1, m)); } } // Store the result dp[left][right][count] = ans; // Return answer return ans; } // Function to remove the elements function maxPoints(arr, n, m) { let len = arr.length; // Function call return helper(arr, 0, len - 1, 0, m); } // Driver Code // Given array let arr = [ 1, 3, 2, 2, 2, 3, 4, 3, 1 ]; let M = 3; let N = arr.length; // Function call document.write(maxPoints(arr, N, M)); // This code is contributed by avanitrachhadiya2155 </script> |
27
Time Complexity: O(N4)
Auxiliary Space: O(N3)
Please Login to comment...