# 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] = 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[0][n - 1] + n/2; ` `} ` ` `  `// Driven Program ` `int` `main() ` `{ ` `    ``int` `arr[] = { 1, 2, 4, 3 }; ` `    ``int` `n = ``sizeof``(arr)/``sizeof``(arr[0]); ` ` `  `    ``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] = 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] = 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``[0][``\$n` `- 1] + ``\$n``/2; ` `} ` `  `  `// Driven Program ` ` `  `\$arr` `= ``array``( 1, 2, 4, 3 ); ` `\$n` `= sizeof(``\$arr``)/sizeof(``\$arr``[0]); ` ` `  `\$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.