Given an array of numbers and a constant k, minimize size of array with following rules for removing elements.

- Exactly three elements can be removed at one go.
- The removed three elements must be adjacent in array, i.e., arr[i], arr[i+1], arr[i+2]. And the second element must be k greater than first and third element must be k greater than second, i.e., arr[i+1] – arr[i] = k and arr[i+2]-arr[i+1] = k.

Example:

Input: arr[] = {2, 3, 4, 5, 6, 4}, k = 1 Output: 0 We can actually remove all elements. First remove 4, 5, 6 => We get {2, 3, 4} Now remove 2, 3, 4 => We get empty array {} Input: arr[] = {2, 3, 4, 7, 6, 4}, k = 1 Output: 3 We can only remove 2 3 4

Source: https://code.google.com/codejam/contest/4214486/dashboard#s=p2

**We strongly recommend you to minimize your browser and try this yourself first.**

For every element arr[i] there are two possibilities

1) Either the element is not removed.

2) OR element is removed (if it follows rules of removal). When an element is removed, there are again two possibilities.

…..a) It may be removed directly, i.e., initial arr[i+1] is arr[i]+k and arr[i+2] is arr[i] + 2*k.

…..b) There exist x and y such that arr[x] – arr[i] = k, arr[y] – arr[x] = k, and subarrays “arr[i+1…x-1]” & “arr[x+1…y-1]” can be completely removed.

Below is recursive algorithm based on above idea.

// Returns size of minimum possible size of arr[low..high] // after removing elements according to given rules findMinSize(arr[], low, high, k) // If there are less than 3 elements in arr[low..high]1)If high-low+1 < 3, return high-low+1 // Consider the case when 'arr[low]' is not considered as // part of any triplet to be removed. Initialize result // using this case2)result = 1 + findMinSize(arr, low+1, high) // Case when 'arr[low]' is part of some triplet and removed // Try all possible triplets that have arr[low]3)For all i from low+1 to high For all j from i+1 to high Update result if all of the following conditions are met a) arr[i] - arr[low] = k b) arr[j] - arr[i] = k c) findMinSize(arr, low+1, i-1, k) returns 0 d) findMinSize(arr, i+1, j-1, k) also returns 0 e) Result calculated for this triplet (low, i, j) is smaller than existing result.4)Return result

The time complexity of above solution is exponential. If we draw the complete recursion tree, we can observer that many subproblems are solved again and again. Since same suproblems are called again, this problem has Overlapping Subprolems property. Like other typical Dynamic Programming(DP) problems, recomputations of same subproblems can be avoided by constructing a temporary array dp[][] to store results of the subproblems. Below is Dynamic Programming based solution

Below is C++ implementation of above idea. The implementation is memoization based, i.e., it is recursive and uses a lookup table dp[][] to check if a subproblem is already solved or not.

## C++

`// C++ program to find size of minimum possible array after ` `// removing elements according to given rules ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` `#define MAX 1000 ` ` ` `// dp[i][j] denotes the minimum number of elements left in ` `// the subarray arr[i..j]. ` `int` `dp[MAX][MAX]; ` ` ` `int` `minSizeRec(` `int` `arr[], ` `int` `low, ` `int` `high, ` `int` `k) ` `{ ` ` ` `// If already evaluated ` ` ` `if` `(dp[low][high] != -1) ` ` ` `return` `dp[low][high]; ` ` ` ` ` `// If size of array is less than 3 ` ` ` `if` `( (high-low + 1) < 3) ` ` ` `return` `high-low +1; ` ` ` ` ` `// Initialize result as the case when first element is ` ` ` `// separated (not removed using given rules) ` ` ` `int` `res = 1 + minSizeRec(arr, low+1, high, k); ` ` ` ` ` `// Now consider all cases when first element forms a triplet ` ` ` `// and removed. Check for all possible triplets (low, i, j) ` ` ` `for` `(` `int` `i = low+1; i<=high-1; i++) ` ` ` `{ ` ` ` `for` `(` `int` `j = i+1; j <= high; j++ ) ` ` ` `{ ` ` ` `// Check if this triplet follows the given rules of ` ` ` `// removal. And elements between 'low' and 'i' , and ` ` ` `// between 'i' and 'j' can be recursively removed. ` ` ` `if` `(arr[i] == (arr[low] + k) && ` ` ` `arr[j] == (arr[low] + 2*k) && ` ` ` `minSizeRec(arr, low+1, i-1, k) == 0 && ` ` ` `minSizeRec(arr, i+1, j-1, k) == 0) ` ` ` `{ ` ` ` `res = min(res, minSizeRec(arr, j+1, high, k)); ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` ` ` `// Insert value in table and return result ` ` ` `return` `(dp[low][high] = res); ` `} ` ` ` `// This function mainlu initializes dp table and calls ` `// recursive function minSizeRec ` `int` `minSize(` `int` `arr[], ` `int` `n, ` `int` `k) ` `{ ` ` ` `memset` `(dp, -1, ` `sizeof` `(dp)); ` ` ` `return` `minSizeRec(arr, 0, n-1, k); ` `} ` ` ` `// Driver prrogram to test above function ` `int` `main() ` `{ ` ` ` `int` `arr[] = {2, 3, 4, 5, 6, 4}; ` ` ` `int` `n = ` `sizeof` `(arr)/` `sizeof` `(arr[0]); ` ` ` `int` `k = 1; ` ` ` `cout << minSize(arr, n, k) << endl; ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Python3

`# Python3 program to find size of ` `# minimum possible array after ` `# removing elements according to given rules ` `MAX` `=` `1000` ` ` `dp` `=` `[[` `-` `1` `for` `i ` `in` `range` `(` `MAX` `)] ` `for` `i ` `in` `range` `(` `MAX` `)] ` `# dp[i][j] denotes the minimum number of elements left in ` `# the subarray arr[i..j]. ` ` ` `def` `minSizeRec(arr,low,high,k): ` ` ` ` ` `# If already evaluated ` ` ` `if` `dp[low][high] !` `=` `-` `1` `: ` ` ` `return` `dp[low][high] ` ` ` ` ` `# If size of array is less than 3 ` ` ` `if` `(high` `-` `low ` `+` `1` `) < ` `3` `: ` ` ` `return` `(high` `-` `low ` `+` `1` `) ` ` ` ` ` `# Initialize result as the case when first element is ` ` ` `# separated (not removed using given rules) ` ` ` `res ` `=` `1` `+` `minSizeRec(arr, low` `+` `1` `, high, k) ` ` ` ` ` `# Now consider all cases when ` ` ` `# first element forms a triplet ` ` ` `# and removed. Check for all possible ` ` ` `# triplets (low, i, j) ` ` ` ` ` `for` `i ` `in` `range` `(low` `+` `1` `,high): ` ` ` ` ` `for` `j ` `in` `range` `(i` `+` `1` `,high` `+` `1` `): ` ` ` ` ` `# Check if this triplet follows the given rules of ` ` ` `# removal. And elements between 'low' and 'i' , and ` ` ` `# between 'i' and 'j' can be recursively removed. ` ` ` `if` `(arr[i]` `=` `=` `(arr[low]` `+` `k) ` `and` `arr[j] ` `=` `=` `(arr[low] ` `+` `2` `*` `k) ` `and` ` ` `minSizeRec(arr, low` `+` `1` `, i` `-` `1` `, k) ` `=` `=` `0` `and` ` ` `minSizeRec(arr, i` `+` `1` `, j` `-` `1` `, k) ` `=` `=` `0` `): ` ` ` `res` `=` `min` `(res,minSizeRec(arr,j` `+` `1` `,high,k) ) ` ` ` ` ` `# Insert value in table and return result ` ` ` `dp[low][high] ` `=` `res ` ` ` `return` `res ` ` ` `# This function mainly initializes dp table and calls ` `# recursive function minSizeRec ` `def` `minSize(arr,n,k): ` ` ` `dp` `=` `[[` `-` `1` `for` `i ` `in` `range` `(` `MAX` `)] ` `for` `i ` `in` `range` `(` `MAX` `)] ` ` ` `return` `minSizeRec(arr, ` `0` `, n` `-` `1` `, k) ` ` ` `# Driver program to test above function ` `if` `__name__` `=` `=` `'__main__'` `: ` ` ` `arr` `=` `[` `2` `, ` `3` `, ` `4` `, ` `5` `, ` `6` `, ` `4` `] ` ` ` `n` `=` `len` `(arr) ` ` ` `k` `=` `1` ` ` `print` `(minSize(arr,n,k)) ` ` ` `# this code is contributed by sahilshelangia ` ` ` |

*chevron_right*

*filter_none*

Output:

0

This article is contributed by Ekta Goel. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

## Recommended Posts:

- Find minimum sum such that one of every three consecutive elements is taken
- Minimum number of elements which are not part of Increasing or decreasing subsequence in array
- Find minimum adjustment cost of an array
- Find maximum points which can be obtained by deleting elements from array
- Non-decreasing subsequence of size k with minimum sum
- Number of arrays of size N whose elements are positive integers and sum is K
- Size of array after repeated deletion of LIS
- Remove minimum elements from either side such that 2*min becomes more than max
- Count the number of ways to tile the floor of size n x m using 1 x m size tiles
- Minimum sum subsequence such that at least one of every four consecutive elements is picked
- Minimum Sum Path In 3-D Array
- Minimum sum submatrix in a given 2D array
- Minimum insertions to sort an array
- Minimum removals from array to make max - min <= K
- Convert to Strictly increasing array with minimum changes