第四章上机报告

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

问题描述: 该问题要求将待排序的序列进行二路合并后进行比较的次数最少,由于题目已经给出给定的原则:两个长度分别为m 和 n的待合并序列 需要进行m + n - 1次比较, 那么我们只需选择最优的合并顺序,使得m+n-1的值为最少即可,反之,若要比较次数最多,也是用这个基本思想。

算法描述

通过对样例输入输出的分析,基本可以知道,若每次选择长度最短的两个序列合并,得出的比较次数是最少的。 直观的说,比如 每次选的 m+n 最少, 那么需要比较的次数也最少,合并之后的再和第三小的合并,如此递增,那么比较次数一定是最少的,这就是基本的贪心策略。如果选择比较次数最多,就每次都要选最大的两个序列进行合并。
在这里,我采用了优先队列的方式,拿最大的比较次数为例,每次都选队列中的第一个元素(因为必定是最大!),然后pop出去,再选第一个元素,此时选择的必定是第二小的元素,那么用sum计算出他们的比较次数后,再把合并后的长度放入到队列中。到最后输出记录的比较次数即可。
反证法:假设该贪心算法不是最优解,那么我们分析 子问题就是每次都选择长度最短的两个序列合并(因为力求比较次数最少),那么子问题合并起来必定是最终问题的最优解,所以贪心算法不是最优解是矛盾的,这一题符合贪心算法的适用范围

复杂度分析: 时间复杂度:开辟了一个队列,将数组元素依次存放,然后在对队列做基本的push 和back操作 复杂度是O(N)
空间复杂度: 开辟了一个队列,将元素放入存储空间 复杂度o(N)

心得体会:这次的题目做起来不算十分顺利,很多不应该犯的错误都犯了,比如将 队列中的 两个最大的元素pop出去之后,却忘了将他们两个合并序列的长度在push回队列中去,而且本题也有更简单的实现方法,没有必要用到优先队列。另外,这次实践的删数问题看似简单,但是实现起来却总是没能过测试点,虽然基本的贪心策略就是 从左向右扫,找到第一个右边的数比左边的数小的话,便删掉左边的数(这是因为能保证最高位的数字尽量少) 但是在打代码的过程中,缺乏了很多边界条件的判定,比如说删完之后k仍然大于0 ,前缀0的处理等等。总的来说,这次上级的收获还是很大的,在有限的时间完成题目,是对自己能力锻炼的很好机会。

posted @ 2019-11-13 23:51  FITZ陈思宇  阅读(166)  评论(0编辑  收藏  举报