Minimum cost to merge numbers from 1 to N
Last Updated :
20 Jul, 2021
Given an integer N, the task is to find the minimum cost to merge all the numbers from 1 to N where the cost of merging two set of numbers A and B is equal to the product of the product of the numbers in the respective sets.
Examples:
Input: N = 4
Output: 32
Merging {1} and {2} costs 1 * 2 = 2
Merging {1, 2} and {3} costs 2 * 3 = 6
Merge{1, 2, 3} and {4} costs 6 * 4 = 24
Hence, the minimal cost is 2 + 6 + 24 = 32
Input: N = 2
Output: 2
Approach:
- The first approach that comes in our mind is sorting. We take first two smallest elements and add them, then continue adding to the rest of the elements in the sorted array. But it fails when the current running sum exceeds the next smallest value in the array coming next.
Take N = 5,
If we take the sorting approach, then-
Merge {1} and {2} - 1 * 2 = 2
Merge {1, 2} and {3} - 2 * 3 = 6
Merge{1, 2, 3} and {4} - 6 * 4 = 24
Merge{1, 2, 3, 4} and {5} - 24 * 5 = 120
Total sum = 152
But optimal way is,
Merge {1} and {2} - 1 * 2 = 2
Merge {1, 2} and {3} - 2 * 3 = 6
Merge {4} and {5} - 4 * 5 = 20
Merge {1, 2, 3} and {4, 5} - 6 * 20 = 120
Total sum = 148
This is the minimal answer.
- So, the correct approach to solve this problem is the Min-heap based approach. Initially, we push all the numbers from 1 to N into the Min-Heap.
- At every iteration, we extract the minimum and the second minimum element from the Min-Heap and insert their product back into it. This ensures that the addition cost generated will be minimum.
- We keep on repeating the above step until there is only one element remaining in the Min-Heap. The calculated sum till that instant gives us the required answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int GetMinCost( int N)
{
priority_queue< int , vector< int >,
greater< int > > pq;
for ( int i = 1; i <= N; i++) {
pq.push(i);
}
int cost = 0;
while (pq.size() > 1)
{
int mini = pq.top();
pq.pop();
int secondmini = pq.top();
pq.pop();
int current = mini * secondmini;
cost += current;
pq.push(current);
}
return cost;
}
int main()
{
int N = 5;
cout << GetMinCost(N);
}
|
Java
import java.util.*;
class GFG {
static int GetMinCost( int N)
{
PriorityQueue<Integer> pq;
pq = new PriorityQueue<>();
for ( int i = 1 ; i <= N; i++)
{
pq.add(i);
}
int cost = 0 ;
while (pq.size() > 1 )
{
int mini = pq.remove();
int secondmini = pq.remove();
int current = mini * secondmini;
cost += current;
pq.add(current);
}
return cost;
}
public static void main(String args[])
{
int N = 5 ;
System.out.println(GetMinCost(N));
}
}
|
Python3
def GetMinCost(N):
pq = []
for i in range ( 1 , N + 1 , 1 ):
pq.append(i)
pq.sort(reverse = False )
cost = 0
while ( len (pq) > 1 ):
mini = pq[ 0 ]
pq.remove(pq[ 0 ])
secondmini = pq[ 0 ]
pq.remove(pq[ 0 ])
current = mini * secondmini
cost + = current
pq.append(current)
pq.sort(reverse = False )
return cost
if __name__ = = '__main__' :
N = 5
print (GetMinCost(N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int GetMinCost( int N)
{
List< int > pq = new List< int >();
for ( int i = 1; i <= N; i++)
{
pq.Add(i);
}
int cost = 0;
pq.Sort();
while (pq.Count > 1)
{
int mini = pq[0];
pq.RemoveAt(0);
int secondmini = pq[0];
pq.RemoveAt(0);
int current = mini * secondmini;
cost += current;
pq.Add(current);
pq.Sort();
}
return cost;
}
static void Main()
{
int N = 5;
Console.WriteLine(GetMinCost(N));
}
}
|
Javascript
<script>
function GetMinCost(N)
{
let pq = [];
for (let i = 1; i <= N; i++)
{
pq.push(i);
}
pq.sort( function (a, b){ return a - b});
let cost = 0;
while (pq.length > 1)
{
let mini = pq[0];
pq.shift();
let secondmini = pq[0];
pq.shift();
let current = mini * secondmini;
cost += current;
pq.push(current);
pq.sort( function (a, b){ return a - b});
}
return cost;
}
let N = 5;
document.write(GetMinCost(N));
</script>
|
Time Complexity: O(NlogN)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...