# 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.

```// C++ program to count minimum operations
// required to remove an array
#include<bits/stdc++.h>
#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;

}
}

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;
}
```

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.

# GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.
4 Average Difficulty : 4/5.0
Based on 7 vote(s)