Minimize sum of prime numbers added to make an array non-decreasing
Given an array arr[], the task is to convert it into a non-decreasing array by adding primes to array elements such that the sum of the primes added is the minimum possible.
Examples:
Input: arr[] = {2, 1, 5, 4, 3}
Output: 7
Explanation:
{2, 1, 5, 4, 3} -> {2, 3, 5, 6, 6}
By changing the 2nd element of array to 3(1 + 2), the 4th element of the array to 6(4 + 2) and the 5th element to 6( 3 + 3).
So, the total cost is 2 + 2 + 3 = 7Input: arr[] = {3, 3, 3, 3}
Output: 10
Approach: The idea is to add the least prime numbers possible to the array elements to make the array non-decreasing. Below are the steps:
- Initialize a variable to store the minimum cost, say res.
- Generate and store all prime numbers up to 107 using the Sieve of Eratosthenes.
- Now, traverse the array and do the following steps:
- If the current element is less than the previous element than find the smallest prime number (say closest_prime) which can be added to make the array non-decreasing.
- Update the current element arr[i] = arr[i] + closest_prime.
- Add closest_prime to res.
- Print the final value of res obtained.
Below is the implementation of the above approach:
C++
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std; #define MAX 10000000 // Stores if an index is a // prime / non-prime value bool isPrime[MAX]; // Stores the prime vector< int > primes; // Function to generate all // prime numbers void SieveOfEratosthenes() { memset (isPrime, true , sizeof (isPrime)); for ( int p = 2; p * p <= MAX; p++) { // If current element is prime if (isPrime[p] == true ) { // Set all its multiples non-prime for ( int i = p * p; i <= MAX; i += p) isPrime[i] = false ; } } // Store all prime numbers for ( int p = 2; p <= MAX; p++) if (isPrime[p]) primes.push_back(p); } // Function to find the closest // prime to a particular number int prime_search(vector< int > primes, int diff) { // Applying binary search // on primes vector int low = 0; int high = primes.size() - 1; int res; while (low <= high) { int mid = (low + high) / 2; // If the prime added makes // the elements equal if (primes[mid] == diff) { // Return this as the // closest prime return primes[mid]; } // If the array remains // non-decreasing else if (primes[mid] < diff) { // Search for a bigger // prime number low = mid + 1; } // Otherwise else { res = primes[mid]; // Check if a smaller prime can // make array non-decreasing or not high = mid - 1; } } // Return closest number return res; } // Function to find the minimum cost int minCost( int arr[], int n) { // Find all primes SieveOfEratosthenes(); // Store the result int res = 0; // Iterate over the array for ( int i = 1; i < n; i++) { // Current element is less // than the previous element if (arr[i] < arr[i - 1]) { int diff = arr[i - 1] - arr[i]; // Find the closest prime which // makes the array non decreasing int closest_prime = prime_search(primes, diff); // Add to overall cost res += closest_prime; // Update current element arr[i] += closest_prime; } } // Return the minimum cost return res; } // Driver Code int main() { // Given array int arr[] = { 2, 1, 5, 4, 3 }; int n = 5; // Function Call cout << minCost(arr, n); return 0; } |
Java
// Java program to implement // the above approach import java.util.*; class GFG{ static final int MAX = 10000000 ; // Stores if an index is a // prime / non-prime value static boolean []isPrime = new boolean [MAX + 1 ]; // Stores the prime static Vector<Integer> primes = new Vector<Integer>(); // Function to generate all // prime numbers static void SieveOfEratosthenes() { Arrays.fill(isPrime, true ); for ( int p = 2 ; p * p <= MAX; p++) { // If current element is prime if (isPrime[p] == true ) { // Set all its multiples non-prime for ( int i = p * p; i <= MAX; i += p) isPrime[i] = false ; } } // Store all prime numbers for ( int p = 2 ; p <= MAX; p++) if (isPrime[p]) primes.add(p); } // Function to find the closest // prime to a particular number static int prime_search(Vector<Integer> primes, int diff) { // Applying binary search // on primes vector int low = 0 ; int high = primes.size() - 1 ; int res = - 1 ; while (low <= high) { int mid = (low + high) / 2 ; // If the prime added makes // the elements equal if (primes.get(mid) == diff) { // Return this as the // closest prime return primes.get(mid); } // If the array remains // non-decreasing else if (primes.get(mid) < diff) { // Search for a bigger // prime number low = mid + 1 ; } // Otherwise else { res = primes.get(mid); // Check if a smaller prime can // make array non-decreasing or not high = mid - 1 ; } } // Return closest number return res; } // Function to find the minimum cost static int minCost( int arr[], int n) { // Find all primes SieveOfEratosthenes(); // Store the result int res = 0 ; // Iterate over the array for ( int i = 1 ; i < n; i++) { // Current element is less // than the previous element if (arr[i] < arr[i - 1 ]) { int diff = arr[i - 1 ] - arr[i]; // Find the closest prime which // makes the array non decreasing int closest_prime = prime_search(primes, diff); // Add to overall cost res += closest_prime; // Update current element arr[i] += closest_prime; } } // Return the minimum cost return res; } // Driver Code public static void main(String[] args) { // Given array int arr[] = { 2 , 1 , 5 , 4 , 3 }; int n = 5 ; // Function call System.out.print(minCost(arr, n)); } } // This code is contributed by Amit Katiyar |
Python3
# Python3 Program to implement # the above approach MAX = 10000000 # Stores if an index is a # prime / non-prime value isPrime = [ True ] * ( MAX + 1 ) # Stores the prime primes = [] # Function to generate all # prime numbers def SieveOfEratosthenes(): global isPrime p = 2 while p * p < = MAX : # If current element is prime if (isPrime[p] = = True ): # Set all its multiples non-prime for i in range (p * p, MAX + 1 , p): isPrime[i] = False p + = 1 # Store all prime numbers for p in range ( 2 , MAX + 1 ): if (isPrime[p]): primes.append(p) # Function to find the closest # prime to a particular number def prime_search(primes, diff): # Applying binary search # on primes vector low = 0 high = len (primes) - 1 while (low < = high): mid = (low + high) / / 2 # If the prime added makes # the elements equal if (primes[mid] = = diff): # Return this as the # closest prime return primes[mid] # If the array remains # non-decreasing elif (primes[mid] < diff): # Search for a bigger # prime number low = mid + 1 # Otherwise else : res = primes[mid] # Check if a smaller prime can # make array non-decreasing or not high = mid - 1 # Return closest number return res # Function to find the minimum cost def minCost(arr, n): # Find all primes SieveOfEratosthenes() # Store the result res = 0 # Iterate over the array for i in range ( 1 , n): # Current element is less # than the previous element if (arr[i] < arr[i - 1 ]): diff = arr[i - 1 ] - arr[i] # Find the closest prime which # makes the array non decreasing closest_prime = prime_search(primes, diff) # Add to overall cost res + = closest_prime # Update current element arr[i] + = closest_prime # Return the minimum cost return res # Driver Code if __name__ = = "__main__" : # Given array arr = [ 2 , 1 , 5 , 4 , 3 ] n = 5 #Function Call print (minCost(arr, n)) # This code is contributed by Chitranayal |
C#
// C# program to implement // the above approach using System; using System.Collections; using System.Collections.Generic; class GFG{ static int MAX = 10000000; // Stores if an index is a // prime / non-prime value static bool []isPrime = new bool [MAX + 1]; // Stores the prime static ArrayList primes = new ArrayList(); // Function to generate all // prime numbers static void SieveOfEratosthenes() { Array.Fill(isPrime, true ); for ( int p = 2; p * p <= MAX; p++) { // If current element is prime if (isPrime[p] == true ) { // Set all its multiples non-prime for ( int i = p * p; i <= MAX; i += p) isPrime[i] = false ; } } // Store all prime numbers for ( int p = 2; p <= MAX; p++) if (isPrime[p]) primes.Add(p); } // Function to find the closest // prime to a particular number static int prime_search(ArrayList primes, int diff) { // Applying binary search // on primes vector int low = 0; int high = primes.Count - 1; int res = -1; while (low <= high) { int mid = (low + high) / 2; // If the prime added makes // the elements equal if (( int )primes[mid] == diff) { // Return this as the // closest prime return ( int )primes[mid]; } // If the array remains // non-decreasing else if (( int )primes[mid] < diff) { // Search for a bigger // prime number low = mid + 1; } // Otherwise else { res = ( int )primes[mid]; // Check if a smaller prime can // make array non-decreasing or not high = mid - 1; } } // Return closest number return res; } // Function to find the minimum cost static int minCost( int []arr, int n) { // Find all primes SieveOfEratosthenes(); // Store the result int res = 0; // Iterate over the array for ( int i = 1; i < n; i++) { // Current element is less // than the previous element if (arr[i] < arr[i - 1]) { int diff = arr[i - 1] - arr[i]; // Find the closest prime which // makes the array non decreasing int closest_prime = prime_search(primes, diff); // Add to overall cost res += closest_prime; // Update current element arr[i] += closest_prime; } } // Return the minimum cost return res; } // Driver Code public static void Main( string [] args) { // Given array int []arr = { 2, 1, 5, 4, 3 }; int n = 5; // Function call Console.Write(minCost(arr, n)); } } // This code is contributed by rutvik_56 |
Javascript
<script> // Javascript Program to implement // the above approach let MAX = 10000000; // Stores if an index is a // prime / non-prime value let isPrime = new Array(MAX); // Stores the prime let primes = new Array(); // Function to generate all // prime numbers function SieveOfEratosthenes() { isPrime.fill( true ); for (let p = 2; p * p <= MAX; p++) { // If current element is prime if (isPrime[p] == true ) { // Set all its multiples non-prime for (let i = p * p; i <= MAX; i += p) isPrime[i] = false ; } } // Store all prime numbers for (let p = 2; p <= MAX; p++) if (isPrime[p]) primes.push(p); } // Function to find the closest // prime to a particular number function prime_search(primes, diff) { // Applying binary search // on primes vector let low = 0; let high = primes.length - 1; let res = 0; while (low <= high) { let mid = Math.floor((low + high) / 2); // If the prime added makes // the elements equal if (primes[mid] == diff) { // Return this as the // closest prime return primes[mid]; } // If the array remains // non-decreasing else if (primes[mid] < diff) { // Search for a bigger // prime number low = mid + 1; } // Otherwise else { res = primes[mid]; // Check if a smaller prime can // make array non-decreasing or not high = mid - 1; } } // Return closest number return res; } // Function to find the minimum cost function minCost(arr, n) { // Find all primes SieveOfEratosthenes(); // Store the result let res = 0; // Iterate over the array for (let i = 1; i < n; i++) { // Current element is less // than the previous element if (arr[i] < arr[i - 1]) { let diff = arr[i - 1] - arr[i]; // Find the closest prime which // makes the array non decreasing let closest_prime = prime_search(primes, diff); // Add to overall cost res += closest_prime; // Update current element arr[i] += closest_prime; } } // Return the minimum cost return res; } // Driver Code // Given array let arr = [ 2, 1, 5, 4, 3 ]; let n = 5; // Function Call document.write(minCost(arr, n)) // This code is contributed by gfgking </script> |
Output:
7
Time Complexity: O(N*log(logN))
Auxiliary Space: O(N)
Please Login to comment...