算法第四章实验报告
1.问题描述
2.算法描述
找最优合并顺序时,先用数组将k个序列各自的长度存起来,然后根据它们的长度大小按从小到大的顺序将他们排好序,之后选取第一第二个合并,得到的比较次数就会是最少的,之后再将合并后的序列,跟剩下未合并的序列再比较排序,然后再选序列长度最短的合并,直至k个序列最终合并成一个;找最差合并顺序也是类似的,只不过要按从大到小的顺序排,其他步骤则跟找最优的一样。这里的算法思想用到了贪心策略,每一步我们都找最短的或最长的来计算,直至找出最优或最差的解。每一步计算完后,都将计算结果存在数组的第一位,然后剩下的数在数组中的位置都往前移一位,然后再进行排列、计算。
3.代码实现
#include <bits/stdc++.h> using namespace std; bool cmp(int a,int b){ return a>b; } int maxSum(int *S1,int k){ int maxsum=0; while(k>1){ sort(S1,S1+k,cmp); maxsum+=S1[0]+S1[1]-1;//长度m+n-1 S1[0]=S1[0]+S1[1]; for(int i=1;i<k-1;i++){ S1[i]=S1[i+1]; } k--; } return maxsum; } int minSum(int *S2,int k){ int minsum=0; while(k>1){ sort(S2,S2+k);//给序列长度排序 minsum+=S2[0]+S2[1]-1;//长度m+n-1 S2[0]=S2[0]+S2[1];//数组中第一二个数相加得到的结果存入数组第一位 for(int i=1;i<k-1;i++){ S2[i]=S2[i+1];//剩下的序列长度在数组中的位置往前移动一位 } k--; } return minsum; } int main(){ int k; cin>>k; int S1[1000],S2[1000]; for(int i=0;i<k;i++){ cin>>S1[i]; S2[i]=S1[i]; } cout<<maxSum(S1,k)<<" "; cout<<minSum(S2,k); }
4.时间复杂度
O(n^2)
5.对贪心算法的理解
贪心算法是一步一步求最优解,不考虑整体,总是做出当前看起来最好的选择。在用贪心算法求解问题时,要先确定好贪心的策略。不过贪心算法虽然可以保证每一步得到的都是最优解,但却无法保证全局解最优。贪心算法可能会常涉及到排序。