# Minimum operations required to remove an array

Given an array of N integers where N is even. There are two kinds of operations allowed on the array.

1. Increase the value of any element A[i] by 1.
2. If two adjacent elements in the array are consecutive prime number, delete both the element. That is, A[i] is a prime number and A[i+1] is the next prime number.

The task is to find the minimum number of operation required to remove all the element of the array.

Examples:

```Input  : arr[] = { 1, 2, 4, 3 }
Output : 5
Minimum 5 operation are required.
1. Increase the 2nd element by 1
{ 1, 2, 4, 3 } -> { 1, 3, 4, 3 }
2. Increase the 3rd element by 1
{ 1, 3, 4, 3 } -> { 1, 3, 5, 3 }
3. Delete the 2nd and 3rd element
{ 1, 3, 5, 3 } -> { 1, 3 }
4. Increase the 1st element by 1
{ 1, 3 } -> { 2, 3 }
5. Delete the 1st and 2nd element
{ 2, 3 } -> { }

Input : arr[] = {10, 12}
Output : 3
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

To remove numbers, we must transform two numbers to two consecutive primes. How to compute the minimum cost of transforming two numbers a, b to two consecutive primes, where the cost is the number of incrementation of both numbers?
We use sieve to precompute prime numbers and then find the first prime p not greater than a and the first greater than p using array.

Once we have computed two nearest prime numbers, we use Dynamic Programming to solve the problem. Let dp[i][j] be the minimum cost of clearing the subarray A[i, j]. If there are two numbers in the array, the answer is easy to find. Now, for N > 2, try any element at position k > i as a pair for A[i], such that there are even number of elements from A[i, j] between A[i] and A[k]. For a fixed k, the minimum cost of clearing A[i, j], i.e dp[i][j], equals dp[i + 1][k – 1] + dp[k + 1][j] + (cost of transforming A[i] and A[k] into consecutive primes). We can compute the answer by iterating over all possible k.
Below is the implementation of above approach:

## C++

 `// C++ program to count minimum operations ` `// required to remove an array ` `#include ` `#define MAX 100005 ` `using` `namespace` `std; ` ` `  `// Return the cost to convert two numbers into ` `// consecutive prime number. ` `int` `cost(``int` `a, ``int` `b, ``int` `prev[], ``int` `nxt[]) ` `{ ` `    ``int` `sub = a + b; ` ` `  `    ``if` `(a <= b && prev[b-1] >= a) ` `        ``return` `nxt[b] + prev[b-1] - a - b; ` ` `  `    ``a = max(a, b); ` `    ``a = nxt[a]; ` `    ``b = nxt[a + 1]; ` ` `  `    ``return` `a + b - sub; ` `} ` ` `  `// Sieve to store next and previous prime ` `// to a number. ` `void` `sieve(``int` `prev[], ``int` `nxt[]) ` `{ ` `    ``int` `pr[MAX] = { 0 }; ` ` `  `    ``pr = 1; ` `    ``for` `(``int` `i = 2; i < MAX; i++) ` `    ``{ ` `        ``if` `(pr[i]) ` `            ``continue``; ` ` `  `        ``for` `(``int` `j = i*2; j < MAX; j += i) ` `            ``pr[j] = 1; ` `    ``} ` ` `  `    ``// Computing next prime each number. ` `    ``for` `(``int` `i = MAX - 1; i; i--) ` `    ``{ ` `        ``if` `(pr[i] == 0) ` `            ``nxt[i] = i; ` `        ``else` `            ``nxt[i] = nxt[i+1]; ` `    ``} ` ` `  `    ``// Computing previous prime each number. ` `    ``for` `(``int` `i = 1; i < MAX; i++) ` `    ``{ ` `        ``if` `(pr[i] == 0) ` `            ``prev[i] = i; ` `        ``else` `            ``prev[i] = prev[i-1]; ` `    ``} ` `} ` ` `  `// Return the minimum number of operation required. ` `int` `minOperation(``int` `arr[], ``int` `nxt[], ``int` `prev[], ``int` `n) ` `{ ` `    ``int` `dp[n + 5][n + 5] = { 0 }; ` ` `  `    ``// For each index. ` `    ``for` `(``int` `r = 0; r < n; r++) ` `    ``{ ` `        ``// Each subarray. ` `        ``for` `(``int` `l = r-1; l >= 0; l -= 2) ` `        ``{ ` `            ``dp[l][r] = INT_MAX; ` ` `  `            ``for` `(``int` `ad = l; ad < r; ad += 2) ` `                ``dp[l][r] = min(dp[l][r], dp[l][ad] + ` `                          ``dp[ad+1][r-1] + ` `                          ``cost(arr[ad], arr[r], prev, nxt)); ` `        ``} ` `    ``} ` ` `  `    ``return` `dp[n - 1] + n/2; ` `} ` ` `  `// Driven Program ` `int` `main() ` `{ ` `    ``int` `arr[] = { 1, 2, 4, 3 }; ` `    ``int` `n = ``sizeof``(arr)/``sizeof``(arr); ` ` `  `    ``int` `nxt[MAX], prev[MAX]; ` `    ``sieve(prev, nxt); ` ` `  `    ``cout << minOperation(arr, nxt, prev, n); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java program to count minimum operations  ` `// required to remove an array  ` `class` `GFG ` `{ ` ` `  `static` `final` `int` `MAX = ``100005``; ` ` `  `// Return the cost to convert two  ` `// numbers into consecutive prime number.  ` `static` `int` `cost(``int` `a, ``int` `b,  ` `                ``int` `prev[], ``int` `nxt[]) ` `{ ` `    ``int` `sub = a + b; ` ` `  `    ``if` `(a <= b && prev[b - ``1``] >= a)  ` `    ``{ ` `        ``return` `nxt[b] + prev[b - ``1``] - a - b; ` `    ``} ` ` `  `    ``a = Math.max(a, b); ` `    ``a = nxt[a]; ` `    ``b = nxt[a + ``1``]; ` ` `  `    ``return` `a + b - sub; ` `} ` ` `  `// Sieve to store next and previous  ` `// prime to a number.  ` `static` `void` `sieve(``int` `prev[], ``int` `nxt[]) ` `{ ` `    ``int` `pr[] = ``new` `int``[MAX]; ` ` `  `    ``pr[``1``] = ``1``; ` `    ``for` `(``int` `i = ``2``; i < MAX; i++)  ` `    ``{ ` `        ``if` `(pr[i] == ``1``)  ` `        ``{ ` `            ``continue``; ` `        ``} ` ` `  `        ``for` `(``int` `j = i * ``2``; j < MAX; j += i)  ` `        ``{ ` `            ``pr[j] = ``1``; ` `        ``} ` `    ``} ` ` `  `    ``// Computing next prime each number.  ` `    ``for` `(``int` `i = MAX - ``2``; i > ``0``; i--)  ` `    ``{ ` `        ``if` `(pr[i] == ``0``)  ` `        ``{ ` `            ``nxt[i] = i; ` `        ``}  ` `        ``else`  `        ``{ ` `            ``nxt[i] = nxt[i + ``1``]; ` `        ``} ` `    ``} ` ` `  `    ``// Computing previous prime each number.  ` `    ``for` `(``int` `i = ``1``; i < MAX; i++) ` `    ``{ ` `        ``if` `(pr[i] == ``0``)  ` `        ``{ ` `            ``prev[i] = i; ` `        ``}  ` `        ``else`  `        ``{ ` `            ``prev[i] = prev[i - ``1``]; ` `        ``} ` `    ``} ` `} ` ` `  `// Return the minimum number  ` `// of operation required.  ` `static` `int` `minOperation(``int` `arr[], ``int` `nxt[], ` `                        ``int` `prev[], ``int` `n)  ` `{ ` `    ``int` `dp[][] = ``new` `int``[n + ``5``][n + ``5``]; ` ` `  `    ``// For each index.  ` `    ``for` `(``int` `r = ``0``; r < n; r++)  ` `    ``{ ` `        ``// Each subarray.  ` `        ``for` `(``int` `l = r - ``1``; l >= ``0``; l -= ``2``) ` `        ``{ ` `            ``dp[l][r] = Integer.MAX_VALUE; ` ` `  `            ``for` `(``int` `ad = l; ad < r; ad += ``2``) ` `            ``{ ` `                ``dp[l][r] = Math.min(dp[l][r], dp[l][ad] +  ` `                                    ``dp[ad + ``1``][r - ``1``] +  ` `                                    ``cost(arr[ad], arr[r],  ` `                                            ``prev, nxt)); ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``return` `dp[``0``][n - ``1``] + n / ``2``; ` `} ` ` `  `// Driver Code ` `public` `static` `void` `main(String args[])  ` `{ ` `    ``int` `arr[] = {``1``, ``2``, ``4``, ``3``}; ` `    ``int` `n = arr.length; ` ` `  `    ``int` `nxt[] = ``new` `int``[MAX], prev[] = ``new` `int``[MAX]; ` `    ``sieve(prev, nxt); ` ` `  `    ``System.out.println(minOperation(arr, nxt, prev, n)); ` `} ` `} ` ` `  `// This code is contributed by 29AjayKumar `

## Python3

 `# Python 3 program to count minimum  ` `# operations required to remove an array  ` `MAX` `=` `100005` `INT_MAX ``=` `10000000` ` `  `# Return the cost to convert two numbers  ` `# into consecutive prime number.  ` `def` `cost(a, b, prev, nxt): ` `    ``sub ``=` `a ``+` `b ` `    ``if` `(a <``=` `b ``and` `prev[b ``-` `1``] >``=` `a):  ` `        ``return` `nxt[b] ``+` `prev[b ``-` `1``] ``-` `a ``-` `b  ` ` `  `    ``a ``=` `max``(a, b) ` `    ``a ``=` `nxt[a]  ` `    ``b ``=` `nxt[a ``+` `1``]  ` `    ``return` `a ``+` `b ``-` `sub ` ` `  `# Sieve to store next and previous  ` `# prime to a number.  ` `def` `sieve(prev, nxt):  ` `    ``pr ``=` `[``0` `for` `i ``in` `range``(``MAX``)]  ` ` `  `    ``pr[``1``] ``=` `1` `    ``for` `i ``in` `range``(``1``, ``MAX``):  ` `        ``if` `(pr[i]):  ` `            ``continue` `        ``for` `j ``in` `range``(i ``*` `2``, ``MAX``, i): ` `            ``pr[j] ``=` `1` ` `  `    ``# Computing next prime each number. ` `    ``for` `i ``in` `range``(``MAX` `-` `2``, ``-``1``, ``-``1``):  ` `        ``if` `(pr[i] ``=``=` `0``):  ` `            ``nxt[i] ``=` `i ` `        ``else``: ` `            ``nxt[i] ``=` `nxt[i ``+` `1``] ` ` `  `    ``# Computing previous prime each number. ` `    ``for` `i ``in` `range``(``1``, ``MAX``):  ` `        ``if` `(pr[i] ``=``=` `0``):  ` `            ``prev[i] ``=` `i  ` `        ``else``: ` `            ``prev[i] ``=` `prev[i ``-` `1``]  ` ` `  `# Return the minimum number of  ` `# operation required.  ` `def` `minOperation(arr, nxt, prev, n):  ` `    ``dp ``=` `[[``0` `for` `i ``in` `range``(n ``+` `5``)] ` `             ``for` `i ``in` `range``(n ``+` `5``)]  ` ` `  `    ``# For each index.  ` `    ``for` `r ``in` `range``(n): ` `         `  `        ``# Each subarray.  ` `        ``for` `l ``in` `range``(r ``-` `1``, ``-``1``, ``-``2``):  ` `            ``dp[l][r] ``=` `INT_MAX;  ` ` `  `            ``for` `ad ``in` `range``(l, r, ``2``):  ` `                ``dp[l][r] ``=` `min``(dp[l][r], dp[l][ad] ``+`  `                               ``dp[ad ``+` `1``][r ``-` `1``] ``+`  `                               ``cost(arr[ad], arr[r], ` `                                         ``prev, nxt)) ` `    ``return` `dp[``0``][n ``-` `1``] ``+` `n ``/``/` `2` ` `  `# Driver Code ` `arr ``=` `[``1``, ``2``, ``4``, ``3``]  ` `n ``=` `len``(arr) ` ` `  `nxt ``=` `[``0` `for` `i ``in` `range``(``MAX``)] ` `prev ``=` `[``0` `for` `i ``in` `range``(``MAX``)]  ` `sieve(prev, nxt) ` `print``(minOperation(arr, nxt, prev, n)) ` ` `  `# This code is contributed by sahishelangia `

## C#

 `// C# program to count minimum operations  ` `// required to remove an array  ` `using` `System; ` `class` `GFG ` `{ ` ` `  `static` `int` `MAX = 100005; ` ` `  `// Return the cost to convert two  ` `// numbers into consecutive prime number.  ` `static` `int` `cost(``int` `a, ``int` `b,  ` `                ``int``[] prev, ``int``[] nxt) ` `{ ` `    ``int` `sub = a + b; ` ` `  `    ``if` `(a <= b && prev[b - 1] >= a)  ` `    ``{ ` `        ``return` `nxt[b] + prev[b - 1] - a - b; ` `    ``} ` ` `  `    ``a = Math.Max(a, b); ` `    ``a = nxt[a]; ` `    ``b = nxt[a + 1]; ` ` `  `    ``return` `a + b - sub; ` `} ` ` `  `// Sieve to store next and previous  ` `// prime to a number.  ` `static` `void` `sieve(``int``[] prev, ``int``[] nxt) ` `{ ` `    ``int``[] pr = ``new` `int``[MAX]; ` ` `  `    ``pr = 1; ` `    ``for` `(``int` `i = 2; i < MAX; i++)  ` `    ``{ ` `        ``if` `(pr[i] == 1)  ` `        ``{ ` `            ``continue``; ` `        ``} ` ` `  `        ``for` `(``int` `j = i * 2; j < MAX; j += i)  ` `        ``{ ` `            ``pr[j] = 1; ` `        ``} ` `    ``} ` ` `  `    ``// Computing next prime each number.  ` `    ``for` `(``int` `i = MAX - 2; i > 0; i--)  ` `    ``{ ` `        ``if` `(pr[i] == 0)  ` `        ``{ ` `            ``nxt[i] = i; ` `        ``}  ` `        ``else` `        ``{ ` `            ``nxt[i] = nxt[i + 1]; ` `        ``} ` `    ``} ` ` `  `    ``// Computing previous prime each number.  ` `    ``for` `(``int` `i = 1; i < MAX; i++) ` `    ``{ ` `        ``if` `(pr[i] == 0)  ` `        ``{ ` `            ``prev[i] = i; ` `        ``}  ` `        ``else` `        ``{ ` `            ``prev[i] = prev[i - 1]; ` `        ``} ` `    ``} ` `} ` ` `  `// Return the minimum number  ` `// of operation required.  ` `static` `int` `minOperation(``int``[] arr, ``int``[] nxt, ` `                        ``int``[] prev, ``int` `n)  ` `{ ` `    ``int``[,] dp = ``new` `int``[n + 5, n + 5]; ` ` `  `    ``// For each index.  ` `    ``for` `(``int` `r = 0; r < n; r++)  ` `    ``{ ` `        ``// Each subarray.  ` `        ``for` `(``int` `l = r - 1; l >= 0; l -= 2) ` `        ``{ ` `            ``dp[l, r] = Int32.MaxValue; ` ` `  `            ``for` `(``int` `ad = l; ad < r; ad += 2) ` `            ``{ ` `                ``dp[l, r] = Math.Min(dp[l, r], dp[l, ad] +  ` `                                    ``dp[ad + 1, r - 1] +  ` `                                    ``cost(arr[ad], arr[r],  ` `                                            ``prev, nxt)); ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``return` `dp[0, n - 1] + n / 2; ` `} ` ` `  `// Driver Code ` `public` `static` `void` `Main()  ` `{ ` `    ``int``[] arr = {1, 2, 4, 3}; ` `    ``int` `n = arr.Length; ` ` `  `    ``int``[] nxt = ``new` `int``[MAX]; ` `    ``int``[] prev = ``new` `int``[MAX]; ` `    ``sieve(prev, nxt); ` ` `  `    ``Console.WriteLine(minOperation(arr, nxt, prev, n)); ` `} ` `} ` ` `  `// This code is contributed by Mukul Singh `

## PHP

 `= ``\$a``) ` `        ``return` `\$nxt``[``\$b``] + ``\$prev``[``\$b``-1] - ``\$a` `- ``\$b``; ` `  `  `    ``\$a` `= max(``\$a``, ``\$b``); ` `    ``\$a` `= ``\$nxt``[``\$a``]; ` `    ``\$b` `= ``\$nxt``[``\$a` `+ 1]; ` `  `  `    ``return` `\$a` `+ ``\$b` `- ``\$sub``; ` `} ` `  `  `// Sieve to store next and previous prime ` `// to a number. ` `function` `sieve(&``\$prev``, &``\$nxt``) ` `{ ` `    ``global` `\$MAX``; ` `    ``\$pr` `= ``array_fill``(0,``\$MAX``,NULL); ` `  `  `    ``\$pr`` = 1; ` `    ``for` `(``\$i` `= 2; ``\$i` `< ``\$MAX``; ``\$i``++) ` `    ``{ ` `        ``if` `(``\$pr``[``\$i``]) ` `            ``continue``; ` `  `  `        ``for` `(``\$j` `= ``\$i``*2; ``\$j` `< ``\$MAX``; ``\$j` `+= ``\$i``) ` `            ``\$pr``[``\$j``] = 1; ` `    ``} ` `  `  `    ``// Computing next prime each number. ` `    ``for` `(``\$i` `= ``\$MAX` `- 1; ``\$i``; ``\$i``--) ` `    ``{ ` `        ``if` `(``\$pr``[``\$i``] == 0) ` `            ``\$nxt``[``\$i``] = ``\$i``; ` `        ``else` `            ``\$nxt``[``\$i``] = ``\$nxt``[``\$i``+1]; ` `    ``} ` `  `  `    ``// Computing previous prime each number. ` `    ``for` `(``\$i` `= 1; ``\$i` `< ``\$MAX``; ``\$i``++) ` `    ``{ ` `        ``if` `(``\$pr``[``\$i``] == 0) ` `            ``\$prev``[``\$i``] = ``\$i``; ` `        ``else` `            ``\$prev``[``\$i``] = ``\$prev``[``\$i``-1]; ` `    ``} ` `} ` `  `  `// Return the minimum number of operation required. ` `function` `minOperation(&``\$arr``, &``\$nxt``, &``\$prev``, ``\$n``) ` `{ ` `    ``global` `\$MAX``; ` `    ``\$dp` `= ``array_fill``(0,(``\$n` `+ 5),``array_fill``(0,(``\$n` `+ 5),NULL)); ` `  `  `    ``// For each index. ` `    ``for` `(``\$r` `= 0; ``\$r` `< ``\$n``; ``\$r``++) ` `    ``{ ` `        ``// Each subarray. ` `        ``for` `(``\$l` `= ``\$r``-1; ``\$l` `>= 0; ``\$l` `-= 2) ` `        ``{ ` `            ``\$dp``[``\$l``][``\$r``] = PHP_INT_MAX; ` `  `  `            ``for` `(``\$ad` `= ``\$l``; ``\$ad` `< ``\$r``; ``\$ad` `+= 2) ` `                ``\$dp``[``\$l``][``\$r``] = min(``\$dp``[``\$l``][``\$r``], ``\$dp``[``\$l``][``\$ad``] + ` `                          ``\$dp``[``\$ad``+1][``\$r``-1] + ` `                          ``cost(``\$arr``[``\$ad``], ``\$arr``[``\$r``], ``\$prev``, ``\$nxt``)); ` `        ``} ` `    ``} ` `  `  `    ``return` `\$dp``[``\$n` `- 1] + ``\$n``/2; ` `} ` `  `  `// Driven Program ` ` `  `\$arr` `= ``array``( 1, 2, 4, 3 ); ` `\$n` `= sizeof(``\$arr``)/sizeof(``\$arr``); ` ` `  `\$nxt` `= ``array_fill``(0,``\$MAX``,NULL); ` `\$prev` `= ``array_fill``(0,``\$MAX``,NULL); ` `sieve(``\$prev``, ``\$nxt``); ` ` `  `echo` `minOperation(``\$arr``, ``\$nxt``, ``\$prev``, ``\$n``); ` ` `  `return` `0; ` `?> `

Output:

```5
```

Time Complexity: O(N3).

This article is contributed by Anuj Chauhan. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

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.

My Personal Notes arrow_drop_up

Article Tags :
Practice Tags :

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.