1.实践题目及问题描述:
7-1 ;2 路合并算法合并 2 个长度分别为m和n的序列需要m+n-1 次比较,用 2 路合并算法将k 个排好序的序列合并成一个序列,设计一个算法确定合并这个序列的最优合并顺序(比较次数最少)和最差合并序列(比较次数最多)。
2.算法描述:
比较次数最少就是每次都是合并序列中较短的两个长度,同理比较次数最多是每次都是先合并序列中较长的两个长度。
如下列代码所示,求最差合并序列步骤是先用sort函数对序列从大到小排序,用一个for循环每次合并当前最大两值,记录合并值;求最优合并序列步骤差不多,唯一不同之处在于每次合并完要再排序,因为合并值不一定是当前序列最小值。
int main() { int k,a[N]; cin>>k; for(int i=0;i<k;i++) cin>>a[i]; sort(a,a+k,cmp); int x=a[0],sum1=0; for(int i=1;i<k;i++) { x=x+a[i]; sum1=sum1+x-1; } sort(a,a+k); int sum2=0; int p=0; while(p<k-1) { int y=a[0]; y=y+a[1]; sum2=sum2+y-1; p=p+1; a[0]=y; for(int j=1;j<k-p;j++) a[j]=a[j+1]; sort(a,a+(k-p)); } cout<<sum1<<" "<<sum2<<endl; return 0; }
3.时间及空间复杂度分析:
求最优合并序列时,在一个循环中用了一个sort函数,所以时间复杂度为O(n*n*logn);用了一个一维数组,所以空间复杂度为O(n)。
4.心得体会:
充分理解了贪心算法,就会思路清晰做题快速。7-1和7-3都是一类型的题,通过排序来做出当前最优选择,在这过程中我熟悉了sort函数用法。7-2删数问题理解起来就困难一点,我虽然想不出,但通过询问他人了解到了做法,开拓了思路。