算法第四章实践报告

Posted marcusjr19

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法第四章实践报告相关的知识,希望对你有一定的参考价值。

程序存储问题

题目:
技术图片

解析:
这道题思路非常简单,就是选取最小的那几个程序放到磁盘里面,直到放不下为止。用贪心算法的思路来说,就是每个子问题都选取当前最小的程序,最终会得到整体的最优解。

由于使用sort函数,该算法的时间复杂度为O(nlogn);由于没有开辟新空间,所以空间复杂度为O(1)。

具体代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
#define MAXLENGTH 1005
int program[MAXLENGTH];
int main() {
????int num; // 文件个数
????int length; // 磁带长度
????int sum = 0; // 可存的程序的长度
????int counter = 0; // 计数器
????cin >> num >> length;
????for (int i = 0; i < num; i++) {
????????cin >> program[i];
????};
????sort(program, program + num);
????for (int i = 0; i < num; i++) {
????????sum += program[i];
????????if (sum <= length) {
????????????counter++;
????????}
????????else {
????????????break;
????????}
????}
????cout << counter << endl;
????system("pause");
????return 0;
}

删数问题

题目如下:
技术图片

解析:
拿到题的时候,应该第一反应是删除这行数字中最大的一个。比如样例:

  1. 178543中删去最大的一个,即8,剩下的数字为17543;
  2. 17543中删去最大的一个,即7,剩下的数字为1543;
  3. 1543中删去最大的一个,即5,剩下的数字为143;
    ····

以此类推,我们可以发现:每次删除的数,都是从第一个数字开始的升序序列的最后一个数!
这样我们的贪心策略就可以变成:每次从第一个数字开始,删去当前的升序序列的最大一个数,一直删到规定的k个数为止。这样,就可以算是由当前的最优解得到最后的最优解。

具体代码如下:

#include<iostream>
#include<string>
using namespace std;
int main() {
????string s;
????int num;// 删除的数字个数
????cin >> s >> num;
????while (num > 0) {
????????for (int i = 0; i < s.size(); i++) {
????????????if (s[i] > s[i + 1]) {
????????????????s.erase(i, 1);
????????????????break;
????????????}
????????}
????????num--;
????};
    
    //除去前导0
????for (int i = 0; i < s.size(); i++) {
????????if (s[0] == '0') {
????????????s.erase(0, 1);
????????}
????}
????cout << s << endl;
????system("pause");
????return 0;
}

最优合并问题

题目如下:
技术图片

解析:
这道题的贪心策略就是每次选取最小/最大的两个数字,从而得到最小/最大的比较次数。
由题意可知,其实是一个哈夫曼树问题:
合并最小的节点,可以获得最小的合并比较次数:
技术图片

合并最大的节点,可以获得最大的合并比较次数:
技术图片

具体代码如下:
(实现时使用了stl的优先队列,非常方便):

#include<iostream>
#include<queue>
using namespace std;
priority_queue<int> q1; // 从大到小的优先队列
priority_queue<int, vector<int>, greater<int> > q2; // 从小到大的优先队列
int main() {
????int num;
????int arr[1005];
????cin >> num;
????int maxtime = 0;
????int mintime = 0;
????for (int i = 0; i < num; i++) {
????????cin >> arr[i];
????????q1.push(arr[i]);
????????q2.push(arr[i]);
????}
    
    // 求出最大的比较次数
????while (true) {
????????if (q1.size() == 1) {
????????????break;
????????}
????????else {
????????????int tmp1 = q1.top();
????????????q1.pop();
????????????int tmp2 = q1.top();
????????????q1.pop();
????????????maxtime += tmp1 + tmp2 - 1;
????????????q1.push(tmp1+tmp2);
????????}
????}
    
    // 求出最小的比较次数
????while (true) {
????????if (q2.size() == 1) {
????????????break;
????????}
????????else {
????????????int tmp1 = q2.top();
????????????q2.pop();
????????????int tmp2 = q2.top();
????????????q2.pop();
????????????mintime += tmp1 + tmp2 - 1;
????????????q2.push(tmp1+tmp2);
????????}
????}
????cout << maxtime << " " << mintime << endl;
????system("pause");
????return 0;
}

结对编程小结

在这次结对编程中和队友依旧配合良好,在我提供了思路或者WA的时候会及时帮我纠正问题所在,以及在最后一题中提出使用优先队列的做法,使代码变得整洁,快速得出了我们所要的答案。谢谢队友再次带飞我。

以上是关于算法第四章实践报告的主要内容,如果未能解决你的问题,请参考以下文章

算法第四章实践报告

算法第四章上机实践报告

算法第四章上机实践报告

贪心算法?我全都要!——算法第四章上机实践报告

算法第四章上机实践报告

算法第四章上机实践报告