算法第4章实践报告
Posted wanna-acm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法第4章实践报告相关的知识,希望对你有一定的参考价值。
1、实践题目:
7-1 最优合并问题
2、问题描述:
给定n 个排好序的序列, 用 2 路合并算法将这k 个序列合并成一个序列。 假设所采用的 2 路合并算法合并 2 个长度分别为q和p的序列需要q+p-1 次比较。试设 计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。 为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。
3、算法描述:
想要得到最少 / 多的比较次数,只需按照每次取出最短 / 长的两个序列进行合并即可。在该算法中,先把n个序列进行一次复制,分成a、b两组,分别用来求最少比较次数和最多比较次数。然后将k个序列按从小到大 / 从大到小进行排序,接着取出两个最小 / 最大的数相加,放在第二个数的位置上,然后从第二个数往后重新进行排序,并重复以上步骤,直到只剩最后两个数为止。
#include <iostream> #include <algorithm> using namespace std; int a[1000]; int b[1000]; bool cmp1(int a,int b){ return a<b; } bool cmp2(int a,int b){ return b<a; } int main(){ int k; cin>>k; for(int i=0;i<k;i++){ cin>>a[i]; b[i]=a[i]; } sort(a,a+k,cmp1); int minc=0; for(int i=1;i<k;i++){ a[i]=a[i-1]+a[i]; minc+=a[i]-1; sort(a+i,a+k,cmp1); } sort(b,b+k,cmp2); int maxc=0; for(int i=1;i<k;i++){ b[i]=b[i-1]+b[i]; maxc+=b[i]-1; sort(b+i,b+k,cmp2); } cout<<maxc<<" "<<minc<<endl; return 0; }
4、复杂度分析:
时间复杂度:由于每次都需要重新进行排序,而每次排序的时间复杂度即为O(n^2),所以该算法的时间复杂度为O(n^2 * (n-1)^2 * (n-2)^2 * ...) = O(n!^2)
空间复杂度:由于需要把n个序列复制出来,进行另一问题的求解,所以该算法需要另外借助k个辅助空间,所以该算法的空间复杂度为O(n)。
5、心得体会:
刚开始做这题时,就想到了解法应该是要我们每次都取最大 / 小的两个数进行相加。但第一次写算法时,忘记了每次相加后得到的那个数不一定是最大 / 小的数,所以出错了。后来多亏partner的提醒,让我发现了这个漏洞,并完善了算法。希望自己在下次思考算法时,能考虑得更加全面,多考虑一些特殊情况。
以上是关于算法第4章实践报告的主要内容,如果未能解决你的问题,请参考以下文章