Given two integer arrays arr[] and cost[] where cost[i] is the cost of choosing arr[i]. The task is to choose a subset with at least two elements such that the GCD of all the elements from the subset is 1 and the cost of choosing those elements is as minimum as possible then print the minimum cost.
Examples:
Input: arr[] = {5, 10, 12, 1}, cost[] = {2, 1, 2, 6}
Output: 4
{5, 12} is the required subset with cost = 2 + 2 = 4Input: arr[] = {50, 100, 150, 200, 300}, cost[] = {2, 3, 4, 5, 6}
Output: -1
No subset possible with gcd = 1
Approach: Add GCD of any two elements to a map, now for every element arr[i] calculate its gcd with all the gcd values found so far (saved in the map) and update map[gcd] = min(map[gcd], map[gcd] + cost[i]). If in the end, map doesn’t contain any entry for gcd = 1 then print -1 else print the stored minimum cost.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
// Function to return the minimum cost required int getMinCost( int arr[], int n, int cost[])
{ // Map to store <gcd, cost> pair where
// cost is the cost to get the current gcd
map< int , int > mp;
mp.clear();
mp[0] = 0;
for ( int i = 0; i < n; i++) {
for ( auto it : mp) {
int gcd = __gcd(arr[i], it.first);
// If current gcd value already exists in map
if (mp.count(gcd) == 1)
// Update the minimum cost
// to get the current gcd
mp[gcd] = min(mp[gcd], it.second + cost[i]);
else
mp[gcd] = it.second + cost[i];
}
}
// If there can be no sub-set such that
// the gcd of all the elements is 1
if (mp[1] == 0)
return -1;
else
return mp[1];
} // Driver code int main()
{ int arr[] = { 5, 10, 12, 1 };
int cost[] = { 2, 1, 2, 6 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << getMinCost(arr, n, cost);
return 0;
} |
// Java implementation of the approach import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
class GFG{
// Function to return the minimum cost required static int getMinCost( int arr[], int n, int cost[])
{ // Map to store <gcd, cost> pair where
// cost is the cost to get the current gcd
Map<Integer,Integer> mp = new ConcurrentHashMap<Integer,Integer>();
mp.clear();
mp.put( 0 , 0 );
for ( int i = 0 ; i < n; i++) {
for (Map.Entry<Integer,Integer> it : mp.entrySet()){
int gcd = __gcd(arr[i], it.getKey());
// If current gcd value already exists in map
if (mp.containsKey(gcd))
// Update the minimum cost
// to get the current gcd
mp.put(gcd, Math.min(mp.get(gcd), it.getValue() + cost[i]));
else
mp.put(gcd,it.getValue() + cost[i]);
}
}
// If there can be no sub-set such that
// the gcd of all the elements is 1
if (!mp.containsKey( 1 ))
return - 1 ;
else
return mp.get( 1 );
} static int __gcd( int a, int b)
{ return b == 0 ? a:__gcd(b, a % b);
} // Driver code public static void main(String[] args)
{ int arr[] = { 5 , 10 , 12 , 1 };
int cost[] = { 2 , 1 , 2 , 6 };
int n = arr.length;
System.out.print(getMinCost(arr, n, cost));
} } // This code is contributed by PrinciRaj1992 |
# Python3 implementation of the approach from math import gcd as __gcd
# Function to return the minimum cost required def getMinCost(arr, n, cost):
# Map to store <gcd, cost> pair where
# cost is the cost to get the current gcd
mp = dict ()
mp[ 0 ] = 0
for i in range (n):
for it in list (mp):
gcd = __gcd(arr[i], it)
# If current gcd value
# already exists in map
if (gcd in mp):
# Update the minimum cost
# to get the current gcd
mp[gcd] = min (mp[gcd],
mp[it] + cost[i])
else :
mp[gcd] = mp[it] + cost[i]
# If there can be no sub-set such that
# the gcd of all the elements is 1
if (mp[ 1 ] = = 0 ):
return - 1
else :
return mp[ 1 ]
# Driver code arr = [ 5 , 10 , 12 , 1 ]
cost = [ 2 , 1 , 2 , 6 ]
n = len (arr)
print (getMinCost(arr, n, cost))
# This code is contributed by Mohit Kumar |
// C# implementation of the approach using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{ static int __gcd( int a, int b)
{
return b == 0? a:__gcd(b, a % b);
}
// Function to return the minimum cost required
static int getMinCost( int [] arr, int n, int [] cost)
{
// Map to store <gcd, cost> pair where
// cost is the cost to get the current gcd
Dictionary< int , int > mp = new Dictionary< int , int >();
mp.Add(0, 0);
for ( int i = 0; i < n; i++)
{
foreach ( int it in mp.Keys.ToList())
{
int gcd = __gcd(arr[i], it);
// If current gcd value already exists in map
if (mp.ContainsKey(gcd))
{
// Update the minimum cost
// to get the current gcd
mp[gcd] = Math.Min(mp[gcd], mp[it] + cost[i]);
}
else
{
mp.Add(gcd, mp[it] + cost[i]);
}
}
}
// If there can be no sub-set such that
// the gcd of all the elements is 1
if (mp[1] == 0)
{
return -1;
}
else
{
return mp[1];
}
}
// Driver code
static public void Main ()
{
int [] arr = { 5, 10, 12, 1 };
int [] cost = { 2, 1, 2, 6 };
int n = arr.Length;
Console.WriteLine(getMinCost(arr, n, cost));
}
} // This code is contributed by avanitrachhadiya2155 |
<script> // JavaScript implementation of the approach // Function to return the minimum cost required function getMinCost(arr,n,cost)
{ // Map to store <gcd, cost> pair where
// cost is the cost to get the current gcd
let mp = new Map();
mp.set(0, 0);
for (let i = 0; i < n; i++) {
for (let [key, value] of mp.entries()){
let gcd = __gcd(arr[i], key);
// If current gcd value already exists in map
if (mp.has(gcd))
// Update the minimum cost
// to get the current gcd
mp.set(gcd, Math.min(mp.get(gcd), value + cost[i]));
else
mp.set(gcd,value + cost[i]);
}
}
// If there can be no sub-set such that
// the gcd of all the elements is 1
if (!mp.has(1))
return -1;
else
return mp.get(1);
} function __gcd(a,b)
{ return b == 0? a:__gcd(b, a % b);
} // Driver code let arr=[5, 10, 12, 1 ]; let cost=[2, 1, 2, 6 ]; let n = arr.length; document.write(getMinCost(arr, n, cost)); // This code is contributed by unknown2108 </script> |
4
Complexity Analysis:
- Time Complexity: O(n2 log(n)) where n is the number of elements.
- Auxiliary Space: O(n)