Choose atleast two elements from array such that their GCD is 1 and cost is minimum

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 = 4



Input: 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:

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Output:

4


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.