• 7-39 最优合并问题——优先队列


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

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

    输出格式:
    输出最多比较次数和最少比较次数。

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

    4
    5 12 11 2
    输出样例:
    在这里给出相应的输出。例如:

    78 52

    分析

    1. 这不就是之前合并果子贪心问题,不断排序,当前可以用贪心来做,但是用stl的优先队列多好,直接一个大根堆,一个小根堆,即可A了这个题;
    2. 通过题目可以发现,合并需要的次数就是序列长度之和减1,所以直接排个序,先结合小的,把产物再去结合后面的,这样合并次数最小;同样最大次数也如此;
    #include
    
    using namespace std;
    
    int n, x, ansMin, ansMax;
    priority_queue<int, vector<int>, greater<int>> q;
    priority_queue<int, vector<int>, less<int>> qq;
    
    int main() {
        cin >> n;
        for (int i = 0; i < n; ++i) {
            cin >> x;
            q.push(x);
            qq.push(x);
        }
        while (q.size() > 1) {
            int a = q.top();
            q.pop();
            int b = q.top();
            q.pop();
            ansMin += (a + b - 1);
            q.push(a + b);
        }
        while (qq.size() > 1) {
            int a = qq.top();
            qq.pop();
            int b = qq.top();
            qq.pop();
            ansMax += (a + b - 1);
            qq.push(a + b);
        }
        cout << ansMax << " " << ansMin;
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    5. 用Rust手把手编写一个Proxy(代理), 通讯协议建立, 为内网穿透做准备
    LeetCode50天刷题计划(Day 14—— 删除链表的倒数第 N 个结点(12.20-13.00)
    Git企业开发级讲解(三)
    【webrtc】rtp包组帧
    uniapp常见兼容性问题
    letcode 2171. 拿出最少数目的魔法豆
    React框架基础
    Python CT图像预处理——nii格式读取、重采样、窗宽窗位设置
    数据要素市场研究资料合集
    DAY54
  • 原文地址:https://blog.csdn.net/weixin_51995229/article/details/128111176