hdu 2850——Load Balancing

来源:互联网 发布:免费票据打印软件 编辑:程序博客网 时间:2024/05/16 17:09

题意:把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
原创粉丝点击