Bailian3725 集合问题优先队列

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bailian3725 集合问题优先队列相关的知识,希望对你有一定的参考价值。

3725:集合问题

总时间限制: 5000ms 内存限制: 65536kB
描述
有一组正整数,总数不超过1000,其中最大值记为M。现要将它们划分成N个集合,使得每个集合的元素之和与M的差的绝对值的和最小。

集合A中当前各元素之和记为SUM(A),称为A的负荷;SUM(A)与M之差的绝对值称为A的负荷与理想负荷的偏差,简称为A的偏差。把这些整数划分成N个集合的方法是:按照从大到小的顺序,依次为每个整数分别选择一个集合;确定一个整数所属集合时,先计算各集合的负荷,将该整数分配给负荷最小的那个集合。

求使得各集合的偏差之和最小的划分方案中,集合的数目N。如果这样的方案不止一种,则输出各方案中,集合数最大的那种方案的集合数N。
输入
共输入K+1个整数。其中第一个整数是K代表要划分的整数总数,后面依次是K个整数的值。K不超过1000。
输出
一个整数,代表集合数N。
样例输入
8
2 4 9
12 16
80 28
72
样例输出
3

问题链接Bailian3725 集合问题
问题简述:(略)
问题分析:(略)
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* Bailian3725 集合问题 */

#include <bits/stdc++.h>

using namespace std;

struct Node 
    int w, sum;
    Node(int a = 0, int s = 0) w = a; sum = s;
    bool operator < (const Node &a) const return sum > a.sum;
;

int main()

    priority_queue<int> q;
    priority_queue<Node> q2;
    Node n;

    int k, a, maxa = 0, maxsum = 1 << 30, ans = 1000 + 1;
    scanf("%d", &k);
    for (int i = 1; i <= k; i++) 
        scanf("%d", &a);
        q.push(a);
        maxa = max(maxa, a);
    

    for (int i = k; i >= 1; i--) 
        priority_queue<int> t(q);
        while (!t.empty()) 
            a = t.top();
            t.pop();
            if ((int)q2.size() < i) q2.push(Node(abs(maxa - a), a));
            else 
                n = q2.top();
                q2.pop();
                n.sum += a;
                n.w = abs(n.sum - maxa);
                q2.push(n);
            
        

        int sum = 0;
        while (!q2.empty()) 
            n = q2.top();
            q2.pop();
            sum += n.w;
        
        if (sum < maxsum) 
            maxsum = sum;
            ans = i;
        
    

    printf("%d\\n", ans);

    return 0;

以上是关于Bailian3725 集合问题优先队列的主要内容,如果未能解决你的问题,请参考以下文章

Bailian4078 实现堆结构模拟+优先队列

Bailian4078 实现堆结构模拟+优先队列

UVA - 10954 Add All (全部相加)(Huffman编码 + 优先队列)

Bailian2886 能被3除尽的数之和进制

Java集合与数据结构——优先级队列的使用及练习

优先队列合并果子