4-2 最优合并问题
问题描述
给定 k 个排好序的序列 s1,s2,...,sks1,s2,...,sk , 用 2 路合并算法将这 k 个序列合并成一个序列。
假设所采用的 2 路合并算法合并 2 个长度分别为 m 和 n 的序列需要 m+n-1次比较。试设计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。
为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。
对于给定的 k 个待合并序列,编程计算最多比较次数和最少比较次数合并方案。
数据输入:
第一行有 1 个正整数 k,表示有 k 个待合并序列。接下来的 1 行中,有 k 个正整数,表示 k 个待合并序列的长度。
Java
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
public class ZuiYouHeBing {
private static int n;
private static int[] len;
private static int[] max;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
PriorityQueue<Integer> minQueue;
PriorityQueue<Integer> maxQueue;
while (true){
n = input.nextInt();
len = new int[n+1];
max = new int[n+1];
minQueue = new PriorityQueue<>(n);//默认升序
maxQueue = new PriorityQueue<>(n, Comparator.reverseOrder());//降序
// strLen = new PriorityQueue<>(n, Comparator.naturalOrder());//升序
// strLen = new PriorityQueue<>(n, Comparator.reverseOrder());//降序
// strLen = new PriorityQueue<>(n, (o1, o2) -> o1.compareTo(o2));//升序
// strLen = new PriorityQueue<>(n, (o1, o2) -> o2.compareTo(o1));//降序
// strLen = new PriorityQueue<>(n, (o2, o1) -> o2.compareTo(o1));//升序
// strLen = new PriorityQueue<>(n, (o2, o1) -> o1.compareTo(o2));//降序
// strLen = new PriorityQueue<>(n, new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return o1.compareTo(o2);//升序
// }
// });
// strLen = new PriorityQueue<>(n, new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return o2.compareTo(o1);//降序
// }
// });
// strLen = new PriorityQueue<>(n, new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return o1-o2;//升序
// }
// });
// strLen = new PriorityQueue<>(n, new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return o2-o1;//降序
// }
// });
for(int i=1; i<=n; i++){
len[i] = input.nextInt();
minQueue.add(len[i]);
maxQueue.add(len[i]);
}
int maxSumByArray = getMaxSumByArray();
int maxSum = getSumByQueue(maxQueue);
int minSum = getSumByQueue(minQueue);
System.out.println("Get max by array: "+maxSumByArray);
System.out.println("Get max by queue: "+maxSum);
System.out.println("Get min by queue: "+minSum);
}
}
private static int getMaxSumByArray(){
Arrays.sort(len);
int maxSum=0;
max[n] = 0;
for(int i=n; i>=1; i--)
max[i-1] = max[i] +len[i];
for(int i=0; i<=n-2; i++)
maxSum += max[i];
maxSum -= n-1;
return maxSum;
}
private static int getSumByQueue(PriorityQueue<Integer> queue){
int tempSum;
int sum = 0;
for(int i=1; i<=n-1; i++){
tempSum = queue.poll() + queue.poll();
sum += tempSum;
queue.add(tempSum);
}
sum -= n-1;
return sum;
}
}
Input & Output
4
5 12 11 2
Get max by array: 78
Get max by queue: 78
Get min by queue: 52
Reference
王晓东《计算机算法设计与分析》(第3版)P129

这篇博客探讨了如何解决最优合并问题,即给定多个已排序序列,通过2路合并算法找到合并顺序以最小化比较次数。文章介绍了问题描述,并提供了使用Java实现的算法,同时讨论了确定最差合并顺序以最大化比较次数的情况。输入输出格式和数据处理方法也进行了说明。
2568

被折叠的 条评论
为什么被折叠?



