hdu 2850——Load Balancing

题意:把N个数分成M堆,要和最大的那堆与和最小的那堆的差最小

思路:优先队列

开始的时候直接按照输入的顺序入队列出队列,结果错了。对于这样一组数据,1000 1000 10000 30000,应该是先排大的后排小的。。

在讨论里面有人出了这样一组数据

300000 200000 110000 110000 110000 110000 60000
最优的是(300000 200000) (110000 110000 110000 110000 60000)这样分,相差为0
个人的理解是,题目中说这种分配的问题是NP难的,也就没有一种很好的算法解决这种问题。所以用了hint里面才说只要比测试数据的答案加上1000小就算对了

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

typedef long long ll;

struct server
{
        int id;
        ll tot;
        bool operator < (const server b) const{
                return tot>b.tot;
        }
};
typedef server mission;
mission mis[100005];
priority_queue<server> q;
int ans[100005];

int main()
{
//freopen("data.txt","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--)
        {
                int n,m;
                while(!q.empty())q.pop();
                scanf("%d%d",&n,&m);
                for(int i=0;i<m;++i)
                {
                        server tmp;
                        tmp.id=i;
                        tmp.tot=0;
                        q.push(tmp);
                }
                printf("%d\n",n);
                bool flag=0;
                for(int i=0;i<n;++i)
                {
                        scanf("%d",&mis[i].tot);
                        mis[i].id=i;
                }
                sort(mis,mis+n);
                for(int i=0;i<n;++i)
                {
//                        cout<<mis[i].tot<<' ';
                        server tmp=q.top();
                        q.pop();
                        ans[mis[i].id]=tmp.id;
                        tmp.tot+=mis[i].tot;
                        q.push(tmp);
                }
//                cout<<endl;
                for(int i=0;i<n;++i)
                {
                        printf("%d ",ans[i]);
                }
                puts("");
        }
        return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值