算法第四章实验报告

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.对贪心算法的理解

贪心算法是一步一步求最优解,不考虑整体,总是做出当前看起来最好的选择。在用贪心算法求解问题时,要先确定好贪心的策略。不过贪心算法虽然可以保证每一步得到的都是最优解,但却无法保证全局解最优。贪心算法可能会常涉及到排序。

posted @ 2021-11-14 15:47  白蔡  阅读(51)  评论(0编辑  收藏  举报