算法第四章作业

1.对贪心算法的理解

贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。也就是说,不从整体最优上加以考虑,做出的只是在某种意义上的局部最优解 。
 
贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯。
 
贪心算法一般按如下步骤进行:
1.建立数学模型来描述问题 
2.把求解的问题分成若干个子问题
3.对每个子问题求解,得到子问题的局部最优解
4.把子问题的解局部最优解合成原来解问题的一个解
 
2.选择题目并说明满足算法性质
 
4-3 最优合并问题

给定k 个排好序的序列, 用 2 路合并算法将这k 个序列合并成一个序列。 假设所采用的 2 路合并算法合并 2 个长度分别为m和n的序列需要m+n-1 次比较。试设 计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。 为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。

输入格式:

第一行有 1 个正整数k,表示有 k个待合并序列。 第二行有 k个正整数,表示 k个待合并序列的长度。

输出格式:

输出最多比较次数和最少比较次数。

输入样例:

在这里给出一组输入。例如:

4
5 12 11 2 
 

输出样例:

在这里给出相应的输出。例如:

78 52


#include<iostream>
#include<algorithm>
using namespace std;
int cmp(int x,int y)
{
    return x>y;
}
int da(int a[],int k)
{
    int min=0;
    for(int i=0;i<k-1;i++){
        sort(a+i,a+k);
        a[i+1]+=a[i];
        min+=a[i+1]-1;
    }
    return min;
}
int xiao(int b[],int k)
{
    int max=0;
    for(int i=0;i<k-1;i++){
        sort(b+i,b+k,cmp);
        b[i+1]+=b[i];
        max+=b[i+1]-1;
    }
    return max;
}
int main()
{
    int k;
    int a[100005];
    int b[100005];
    cin>>k;
    for(int i=0;i<k;i++){
        cin>>a[i];
        b[i]=a[i];
    }
    cout<<xiao(b,k)<<" "<<da(a,k)<<endl;
}

运用的数学模型:将所得的数据先由小到大排序,而后求最小两个数之和,再将此结果与其他数据再次排序,可得最少比较次数;以此类推,从大到小排序可得出最多比较次数。这样就可以把问题化成每次只求两个数之和,并整体排序。

遇到的问题:在运用贪心算法时,建立数学模型常常是问题的关键,比如在这道题中,我们一开始只认为比较次数与排序有关,因此直接在排好序后从头加到尾直接输出,但在实际运算中,发现有时相比顺序增加,相同的数字先进行相加运算,会得出更少的结果,如“2,2,3,3”,若只按照顺序增加,最后得出的最少次数是18,但如果两个2和两个3分别先相加,最后得出的最少次数是8。因此我们想到,需要在每一次相加运算后再进行一次排序,排出新的最小的两个数。

结对编程情况:两个人更加默契了,解决问题的效率也在提高。



posted @ 2020-11-15 09:15  我来打题了  阅读(222)  评论(0编辑  收藏  举报