给定一个整数N ,任务是找到合并从1到N 的所有数字的最小成本,其中合并两组数字 A 和 B 的成本等于相应集合中数字的乘积的乘积。
例子:
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
方法:
- 我们想到的第一种方法是排序。我们取前两个最小的元素并添加它们,然后继续添加到排序数组中的其余元素。但是当当前的运行总和超过下一个数组中的下一个最小值时,它就会失败。
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.
- 因此,解决这个问题的正确方法是基于最小堆的方法。最初,我们将所有从1到N的数字推送到最小堆中。
- 在每次迭代中,我们从 Min-Heap 中提取最小值和第二个最小值元素,并将它们的乘积重新插入其中。这确保了产生的附加成本最小。
- 我们不断重复上述步骤,直到 Min-Heap 中只剩下一个元素。直到那一刻的计算总和为我们提供了所需的答案。
下面是上述方法的实现:
C++
// C++ program to find the Minimum
// cost to merge numbers
// from 1 to N.
#include
using namespace std;
// Function returns the
// minimum cost
int GetMinCost(int N)
{
// Min Heap representation
priority_queue,
greater > pq;
// Add all elements to heap
for (int i = 1; i <= N; i++) {
pq.push(i);
}
int cost = 0;
while (pq.size() > 1)
{
// First minimum
int mini = pq.top();
pq.pop();
// Second minimum
int secondmini = pq.top();
pq.pop();
// Multiply them
int current = mini * secondmini;
// Add to the cost
cost += current;
// Push the product into the
// heap again
pq.push(current);
}
// Return the optimal cost
return cost;
}
// Driver code
int main()
{
int N = 5;
cout << GetMinCost(N);
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function returns the
// minimum cost
static int GetMinCost(int N)
{
// Min Heap representation
PriorityQueue pq;
pq = new PriorityQueue<>();
// Add all elements to heap
for(int i = 1; i <= N; i++)
{
pq.add(i);
}
int cost = 0;
while (pq.size() > 1)
{
// First minimum
int mini = pq.remove();
// Second minimum
int secondmini = pq.remove();
// Multiply them
int current = mini * secondmini;
// Add to the cost
cost += current;
// Push the product into the
// heap again
pq.add(current);
}
// Return the optimal cost
return cost;
}
// Driver Code
public static void main(String args[])
{
int N = 5;
// Function call
System.out.println(GetMinCost(N));
}
}
// This code is contributed by rutvik_56
Python3
# python3 program to find the Minimum
# cost to merge numbers
# from 1 to N.
# Function returns the
# minimum cost
def GetMinCost(N):
# Min Heap representation
pq = []
# Add all elements to heap
for i in range(1, N+1, 1):
pq.append(i)
pq.sort(reverse = False)
cost = 0
while (len(pq) > 1):
# First minimum
mini = pq[0]
pq.remove(pq[0])
# Second minimum
secondmini = pq[0]
pq.remove(pq[0])
# Multiply them
current = mini * secondmini
# Add to the cost
cost += current
# Push the product into the
# heap again
pq.append(current)
pq.sort(reverse = False)
# Return the optimal cost
return cost
# Driver code
if __name__ == '__main__':
N = 5
print(GetMinCost(N))
# This code is contributed by Bhupendra_Singh
C#
// C# program to find the Minimum
// cost to merge numbers
// from 1 to N.
using System;
using System.Collections.Generic;
class GFG{
// Function returns the
// minimum cost
static int GetMinCost(int N)
{
// Min Heap representation
List pq = new List();
// Add all elements to heap
for(int i = 1; i <= N; i++)
{
pq.Add(i);
}
int cost = 0;
pq.Sort();
while (pq.Count > 1)
{
// First minimum
int mini = pq[0];
pq.RemoveAt(0);
// Second minimum
int secondmini = pq[0];
pq.RemoveAt(0);
// Multiply them
int current = mini * secondmini;
// Add to the cost
cost += current;
// Push the product into the
// heap again
pq.Add(current);
pq.Sort();
}
// Return the optimal cost
return cost;
}
// Driver code
static void Main()
{
int N = 5;
Console.WriteLine(GetMinCost(N));
}
}
// This code is contributed by divyeshrabadiya07
Javascript
输出:
148
时间复杂度: O(NlogN)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。