Bailian3725 集合问题优先队列
Posted 海岛Blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bailian3725 集合问题优先队列相关的知识,希望对你有一定的参考价值。
总时间限制: 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 集合问题优先队列的主要内容,如果未能解决你的问题,请参考以下文章