版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/seagal890/article/details/89605356
JAVA算法:连接绳索的最小成本
有n根不同长度的绳子,我们需要把这些绳子连接成一根绳子。连接两根绳子的费用等于它们的长度之和。我们需要以最低的成本连接绳索。
例如,如果我们有4根绳子,长度分别为4、3、2和6。我们可以用以下方法连接绳子。
1)首先连接长度为2和3的绳索。现在我们有三根绳子,长度分别是4、6和5。
2)现在连接长度为4和5的绳索。现在我们有两条长度为6和9的绳子。
3)最后连接两条绳索,所有绳索都已连接。
所有绳索的连接总成本为5+9+15=29。这是连接绳索的最佳成本。其他连接绳索的方法总是有相同或更多的成本。例如,如果我们先连接4和6(我们得到3、2和10的三个字符串),然后连接10和3(我们得到13和2的两个字符串)。最后我们连接13和2。这样的总成本是10+13+15=38。
问题分析
如果我们仔细观察上述问题,我们可以注意到,首先挑选的绳索长度包含在总成本中不止一次。因此,我们的想法是先连接最小的两条绳子,然后对剩余的绳子进行循环。这种方法类似于哈夫曼编码。我们把最小的绳子放在树上,这样它们就可以重复多次,而不是更长的绳子。
下面是一个完整的算法,用于寻找连接n根绳索的最低成本。
让一个数组len[0..n-1]中存储n条长度的绳子。
1)创建一个最小堆,并将所有长度插入最小堆。
2)当min堆中的元素数不是1时执行以下操作。
……a)从最小堆中提取最小值和第二个最小值
……b)将上述两个提取值相加,并将其插入min堆。
……c)保持总成本的变量,并不断增加提取值之和。
算法设计
package com.bean.algorithm.basic;
import java.util.PriorityQueue;
public class ConnectRopes {
// Java program to connect n
// ropes with minimum cost
static int minCost(int arr[], int n) {
// Create a priority queue
PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
// Adding items to the pQueue
for (int i = 0; i < n; i++) {
pq.add(arr[i]);
}
// Initialize result
int res = 0;
// While size of priority queue
// is more than 1
while (pq.size() > 1) {
// Extract shortest two ropes from pq
int first = pq.poll();
int second = pq.poll();
// Connect the ropes: update result
// and insert the new rope to pq
res += first + second;
pq.add(first + second);
}
return res;
}
// Driver program to test above function
public static void main(String args[]) {
int len[] = { 4, 3, 2, 6 };
int size = len.length;
System.out.println("Total cost for connecting" + " ropes is " + minCost(len, size));
}
}
程序运行结果
Total cost for connecting ropes is 29