标签:names 时间复杂度 哈夫曼 大小 开始 nbsp using style 体会
一、实践题目:最优合并问题
二、问题描述:给定k 个排好序的序列, 用 2 路合并算法将这k 个序列合并成一个序列。 设所采用的 2 路合并算法合并 2 个长度分别为m和n的序列需要m+n-1 次比较,
求最多比较次数和最少比较次数。
三、算法描述:类似于构建哈夫曼树的思想,求最少比较次数时,每次从已有序列中选择长度最小的两个序列合并成一个新的序列,加入到原序列中,统计比较次数。不断重复该操作,直到只剩最后一个序列。
求最多比较次数时,只需选择长度最大的两个序列合并即可,其他操作相同。
#include<iostream> #include<algorithm> using namespace std; int main(){ int n; cin>>n; int a[n]; int b[n]; for(int i=0;i<n;i++){ cin>>a[i]; b[i]=a[i]; } int min=0; int minSum=0; int index=0; for(int i=1;i<=n-1;i++){ sort(a+index,a+n);//求最少合并次数时,每次合并需重新排序 min=a[index]+a[index+1]; minSum +=min; a[index+1]=min;//合并后的序列加入原序列 index ++; } minSum =minSum-n+1; int max=0; int maxSum=0; index=0; sort(b+index,b+n,greater<int>());//求最多合并次数时,只需排序一次 for(int i=1;i<=n-1;i++){ max=b[index]+b[index+1]; maxSum +=max; b[index+1]=max;合并后的序列加入原序列 index++; } maxSum =maxSum-n+1; cout<<maxSum<<" "<<minSum; }
四、算法分析
时间复杂度:求最少合并次数时,需要合并N-1次,每次合并需要排序,排序的时间复杂度为O(nlogn),综合时间复杂度为O(n^2logn);
求最多合并次数时,需要合并N-1次,但只需一次排序,排序的时间复杂度为O(nlogn),综合时间复杂度为O(nlongn);
所以,总体的时间复杂度为O(n^2logn)。
空间复杂度:使用了两个数组分别计算两个问题,数组大小为O(n),所以空间复杂度为O(n)。
五、心得体会
最优合并问题和程序存储问题的思路都比较清晰,代码设计起来也比较简单,没什么大问题。但是删数问题我们两当初把问题想得太简单了,选择的策略是每次删除最大的一个数,没一会就找出了反例,后来发现贪心选择需要分不同的情况选择:从最高位开始,若各位数字递增,则删除最后一个数字,否则删除第一个递减区间的首字符。依据该策略,我们很快就得到了问题的解。我们俩编程时,往往让思路比较清晰的那个人来打代码,另一个人从旁审查并提出修改意见,对我们解题的效率有很大提升。
标签:names 时间复杂度 哈夫曼 大小 开始 nbsp using style 体会
原文地址:https://www.cnblogs.com/underdestiny/p/10049661.html