算法第四章作业
1. 你对贪心算法的理解
贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。由于不是从整体来考虑最优解,所以有些问题就无法通过贪心算法获得最优解,但是还是有相当一部分问题通过贪心算法能求得最优解的近似解。
2. 最优合并问题
给定k 个排好序的序列, 用 2 路合并算法将这k 个序列合并成一个序列。 假设所采用的 2 路合并算法合并 2 个长度分别为m和n的序列需要m+n-1 次比较。试设 计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。 为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。
输入格式:
第一行有 1 个正整数k,表示有 k个待合并序列。 第二行有 k个正整数,表示 k个待合并序列的长度。
输出格式:
输出最多比较次数和最少比较次数。
输入样例:
4
5 12 11 2
输出样例:
78 52
1 #include<iostream> 2 #include<algorithm> 3 #include<queue> 4 5 using namespace std; 6 7 int maxCmp(int k, int a[]) 8 {//每次都选取两个最大的 9 sort(a, a+k); 10 11 int max = a[k-1]; 12 int sum = 0; 13 for(int i=k-2; i>=0; i--) 14 { 15 sum += max + a[i] - 1; 16 max = max + a[i]; 17 } 18 return sum; 19 } 20 21 int minCmp(int k, int a[]) 22 { 23 priority_queue<int,vector<int>,greater<int> > q;//自动排序 24 for(int i = 0; i < k; i++) 25 q.push(a[i]); 26 int sum = 0; 27 while(q.size() >= 2) 28 { 29 //每次取出最小的两个序列进行合并 30 int x = q.top(); 31 q.pop(); 32 int y = q.top(); 33 q.pop(); 34 sum += x + y - 1; //合并次数 35 q.push(x+y); //合并后的序列长度继续放入数组 36 } 37 38 return sum; 39 } 40 41 int main() 42 { 43 int k; 44 int a[10000]; 45 bool b[10000] = {0};//记录是否被比较过了 46 47 cin >> k; 48 for(int i=0; i<k; i++) 49 { 50 cin >> a[i]; 51 } 52 53 cout << maxCmp(k, a) << " " << minCmp(k, a); 54 55 return 0; 56 }
算法:最优合并顺序的贪心策略就是每次都选取两个最小的序列进行合并,而最差的是每次都选取两个最大的序列进行合并。
3. 请说明在本章学习过程中遇到的问题及结对编程的情况
遇到的问题:在做题的时候,没有看清题目的意思,因此两个人都一直卡在那里,后来重新看了一遍题目,才发现我们原来的理解是错误的。