• 第四章上机实践报告


    1.实践题目

    7-1 最优合并问题 (100 分)

    题目来源:王晓东《算法设计与分析》

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

    输入样例:

    4

    5 12 11 2

    输出样例:

    78 52

     

    2.问题描述

    将几个序列合并成一个序列,序列的比较次数的计算方式是序列长度分别为m和n的序列为m+n-1 次。序列的最差合并顺序就是先合并长的再合并短的,序列的最优合并顺序应优先合并最短的。

    3.算法描述

    Min_sum=(2+5-1)+(2+5+11-1)+(2+5+11+12-1)=52

    Max_sum=(12+11-1)+(12+11+5-1)+(12+11+5+2-1)=78

    先将序列长度进行排序,计算最优合并顺序的是先合并最短的两个序列,用min_sum记录比较次数,min_sum=a[min_index]+a[min_index+1]-1,用a[min_index]存放合并之后的那个序列,同时将a[min_index+1]置为0,min_index++;再重新排序得到新的列表。(重新排序的原因是因为合并之后的序列有可能比原先的序列都大,这个有点类似哈夫曼树)。以上重复n-1次。

    计算最差合并顺序则只需要排序一次就可以,合并两个最长的序列得到的序列也自然是最长的。用max_sum记录比较次数,从排序好数组的数组最后开始循环,计算比较次数,max_sum=a[k-1]+a[k-2]-1。

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int main(){
        int n;
        cin>>n;
        int a[n],b[n];
        for (int i=0;i<n;i++){
            cin>>a[i];
            b[i]=a[i];
            
        }
        sort(a,a+n);
        int min_sum=0,min_index=0; 
        while (min_index<n-1){
            min_sum=min_sum+a[min_index]+a[min_index+1]-1;
            a[min_index]=a[min_index]+a[min_index+1];
            a[min_index+1]=0;
            min_index++;
            sort(a,a+n);    
        }
        sort(b,b+n);
        int max_sum=0,max_temp=b[n-1];
        for (int i=n-2;i>=0;i--){
            max_temp+=b[i];
            max_sum=max_sum+max_temp-1;
            //cout<<i<<"--"<<max_sum<<endl;
        }
        cout<<max_sum<<" "<<min_sum;
        return 0;
        
    } 

    4.算法时间及空间复杂度分析(要有分析过程)

    时间复杂度:直接进行排序是O(n*logn),计算min_sum要进行n次排序,所以为O(n^2logn)。

    空间复杂度:两个数组的大小,O(n)。

    5.心得体会(对本次实践收获及疑惑进行总结)

    首先,一开始做出来题目又是段错误,修改了定义数组大小之后就解决了这个问题,这已经不是第一次遇到这种问题了,真的要规范自己的代码,处理好细节,不然debug的时候真的太难受了。

    其次,一开始按着样例打的代码,没有考虑到合并之后的序列可能不是最小的序列,这里纠结了好久才想到了错误的地方,以后做题不能只看样例,要仔细研究题目,多举几个例子,确定好思路再去打代码,不然总是在做无用功。

  • 相关阅读:
    第一讲 jQuery入门
    Log4j日志记录
    第四讲 Hibernate 缓存管理
    第一讲 Hibernate 简介
    第三讲 Spring 持久层封装、事务控制
    对 PInvoke 函数的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标
    善用 C# 3.0 Extensions 方法
    .net 下如何将文档文件(Word, Pdf等) 中的文本提取出来(转)
    vs2010常用快捷键 (转)
    Silverlight 视频学习札记(一)
  • 原文地址:https://www.cnblogs.com/icyk/p/10051711.html
Copyright © 2020-2023  润新知