第四章实践报告

一、题目:最优合并问题 
二、题目描述:

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

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

 

三、算法描述

1、代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
4 int main() 5 { 6 int k; 7 cin>>k; 8 int a[k],b[k]; 9 for(int i=0;i<k;i++) 10 { 11 cin>>a[i]; 12 } 13 sort(a,a+k); 14 for(int i=k-1,j=0;i>=0;i--,j++) 15 { 16 b[j]=a[i]; 17 } 18 int sum1=0,sum2=0; 19 for(int i=0;i<k-1;i++) 20 { 21 a[i+1]=a[i]+a[i+1]; 22 sum1+=a[i+1]; 23 sort(a+i,a+k); 24 } 25 for(int j=0;j<k-1;j++) 26 { 27 b[j+1]=b[j]+b[j+1]; 28 sum2+=b[j+1]; 29 } 30 cout<<sum2-k+1<<" "; 31 cout<<sum1-k+1<<endl; 32 return 0; 33 }
2、算法解析:

贪心策略:每次选最小的序列合并得到最少比较次数;每次选最大的序列合并得到最多比较次数。
2 个长度分别为m和n的序列需要m + n -1次比较
最少比较次数=(2+5-1)+(2+5+11-1)+(2+5+11+12-1)

最多比较次数=(12+11-1)+ (12+11+5-1 )+ (12+11+5 +2 -1)

用sort函数讲k个数组的元素个数升序排序,计算此时最小序列合并的比较次数(此时还没有-1,在最后输出时一次性-(k-1)),此时并将值赋给sum1,在用sort函数重新升序排序。

用b[]来存储k个数组的元素个数的降序排序,计算此时的最大序列的合并比较次数,(此时还没有-1,在最后输出时一次性-(k-1)),此时并将值赋给sum2,并不需要重新排序。

四、算法空间和时间复杂度分析

创建了两个数组,所以在此空间复杂度为O(k2),输入数组的时候的时间复杂度为O(k),第一次直接排序的时候时间复杂度为O(k *log k),第二次在进行求最好的情况的比较次数的时候的空间复杂度为O(k*k*log k),最后进行最坏情况的比较次数的计算的时候时间复杂度为O(k),其他的计算时间复杂度为常数O(1);故总的时间复杂度为O(k*k*log k);

五、心得体会

虽然当时候由于个人有点事并没有到实验室进行算法的设计,可通过自己的慢慢摸索还是解决了,因而在该实验题上并没有什么设计难度。在此看来最优合并问题使用贪心算法还是很简单的得出最优解得。

posted on 2018-12-02 20:33  岑志健  阅读(222)  评论(0)    收藏  举报