算法设计与分析——4

第四章实验报告

4-3 最优合并问题 

1. 问题描述

    给定k个排好序的序列,用2路合并算法将这k个序列合并成一个序列。假设所采用的2路合并算法合并 2 个长度分别为m和n的序列需要m+n-1次比较。试设计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。 为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。

    输入格式:第一行有 1 个正整数k,表示有 k个待合并序列。 第二行有 k个正整数,表示 k个待合并序列的长度。

    输出格式:输出最多比较次数和最少比较次数。

    输入样例:4 // 5 12 11 2

    输出样例:78 52

2. 算法描述

    主要思路:合并k个序列,需要合并k-1次,每次合并的比较次数取决于俩序列长度和。贪心策略为,比较次数最多,即每次尽可能选择长度最大两序列进行合并,比较次数最少,即每次尽可能选择长度最小两序列进行合并。使用替换法证明,若合并时选择的非长度最大/最小,则总是存在更优的选择方法是比较次数更多/更少,因此该贪心策略成立。

   int MinSum(int a[], int n) {

     int min_sum = 0;  //存放比较总次数

     for (int i = 0; i < n-1; i++) {
       sort(a, a + n);  //排序
       a[i+1] = a[i] + a[i+1];  //总选择最小两个(非最前两个需要除去前方的0)相加赋给其中一个
       a[i] = 0;  //另外一个置为零
       min_sum += a[i+1] - 1;  //更新比较次数
     }
     return min_sum;
   }

 

   int MaxSum(int b[], int n) {
     int max_sum = 0;  //存放比较总次数
     for (int i = 0; i < n-1; i++) {
       sort(b, b + n);  //排序
       b[n-2] = b[n-2] + b[n-1];  //总选择最大两个(最后两个)相加赋给其中一个
       b[n-1] = 0;  //另外一个置为零
       max_sum += b[n-2] - 1;  //更新比较次数
     }
   return max_sum;
   }

3. 时间复杂度分析

需要合并n-1次,每次都需要进行排序,更新序列长度以及比较次数,整个问题的时间复杂度为O(n^2*logn)。

4. 心得体会

此类问题最重要的、难点就在于贪心算法的选择,我们在选择贪心算法时,需要多个方面兼顾考虑,不能全靠感觉和常识,需要进一步的考虑。区分贪心算法问题和动态规划问题之间的不同,选择合适的策略解决问题。

 

 

posted @ 2021-11-16 21:26  alleyn  阅读(23)  评论(0编辑  收藏  举报