计硕三班 吴佳蕊 2022222275 第四章作业

ReeeeJ 2022-12-30 20:06:44

目录

 

1. 概括第四章学习内容,总结第四章学习心得。

2. 以{0-1}背包问题和背包问题为例,讨论动态规划算法与贪心算法的异同。

3. 算法实验2:完成教材114页算法实现题4-2,总结实验出现问题及解决方法。

5. 算法实验2:完成教材118页算法实现题4-14,总结实验出现问题及解决方法。


1. 概括第四章学习内容,总结第四章学习心得。

学习内容:

心得:通过本章内容的学习,理解了贪心算法的概念,掌握了贪心算法的基本要素和求解步骤,明白贪心算法与动态规划算法之间的差异,贪心算法与动态规划算法有点类似,但又有所区别。贪心算法是选择当前一步的最优选择,即局部最优解,在一些选择问题上往往比动态规划法更加直接明了且更为简洁,但把所有步骤完成之后,往往也能得到整体的最优解。总之,贪心算法也是一种追求效益最大化的解决问题方法,但也离不开最优子结构的基本性质,都是从小问题上找最优解进而得到问题最优解的过程。但是对于贪心算法的思想在具体实例中的应用理解不够深刻,具体分析了各个实例,对各个问题中的贪心算法的思想有了进一步理解,未来还需要结合更多其他实例理解贪心算法。

2. 以{0-1}背包问题和背包问题为例,讨论动态规划算法与贪心算法的异同。

 

3. 算法实验2:完成教材114页算法实现题4-2总结实验出现问题及解决方法。

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

代码:

#include <bits/stdc++.h>
using namespace std;
bool cmp(int a, int b){
return a>b;
}
int main(){
int k;
int a[1000], b[1000];
int Min = 0, Max = 0;
cin>>k;
for(int i=0; i<k; i++)
{
cin>>a[i];
b[i]= a[i];
}
sort(a, a+k);
sort(b, b+k, cmp);
for(int i=0; i<k-1; i++)
{
a[i+1] = a[i]+a[i+1];
Min += a[i+1]-1;
sort(a+i+1, a+k);

b[i+1] = b[i]+b[i+1];
Max += b[i+1]-1;
sort(b+i+1, b+k ,cmp);
}
cout<<Max<<' '<<Min<<endl;
return 0;
}

运行:

实验分析:

本题运用的是贪心算法。由于长度分别为m和n的两个序列需要进行m+n-1 次比较,因此最优合并排序总比较次数一定是按序列长度从小到大并依次比较而得,最差合并排序总比较次数则相反,按照序列长度从大到小并依次比较而得。长度最小的两个序列比较相加后长度为m+n,接着再与剩余最小长度的序列比较,以此类推。因此只需要设置两个长度分别为序列个数的数组,一个按照从小到大排,另一个从大到小排,第一个和第二个元素相加后再返回所在数组重新排序,与下一个最小的元素继续累加。本问题有点类似哈夫曼编码问题,当求最优合并排序时,长度越小的序列所代表的点离二叉树的根结点越远。求最差合并排序时则相反。

时间复杂度:

最少比较次数:O(nlogn)

最多比较次数:O(n)

空间复杂度:O(n)

5. 算法实验2:完成教材118页算法实现题4-14总结实验出现问题及解决方法。

多元Huffman编码问题:在一个操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次至少选2堆,最多选k堆石子合并成新的一堆,合并的费用为新的一堆的石子数。试设计一个算法,计算出将n堆石子合并成一堆的最大总费用和最小总费用。

代码:

#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    priority_queue <int> queue1;
    priority_queue <int, vector <int>, greater <int> > queue2;
    int n, k;
    int x;
    long long sum1, sum2;
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &x);
        queue1.push(x);
        queue2.push(x);
    }
    sum1 = 0;
    while(queue1.size() > 1)
    {
        int num1 = queue1.top();
        queue1.pop();
        int num2 = queue1.top();
        queue1.pop();
        queue1.push(num1 + num2);
        sum1 += num1 + num2;
    }
    while(queue2.size() % (k - 1) != 1) queue2.push(0);
 
    sum2 = 0;
    while(queue2.size() > 1)
    {
        int num2;
        int temp = 0;
        for(int i = 1; i <= k; i++)
        {
            num2 = queue2.top();
            queue2.pop();
            temp += num2;
        }
        queue2.push(temp);
        sum2 += temp;
    }
    printf("%lld %lld\n", sum1, sum2);
}

运行:

 

 

...全文
173 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

145

社区成员

发帖
与我相关
我的任务
社区描述
高校教学社区
软件工程 高校
社区管理员
  • dainwnu
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧