hdu 3866(贪心)

来源:互联网 发布:python 字典推导式 编辑:程序博客网 时间:2024/05/18 00:07

给出一个物品的价格,和N个人。每个人最多凑a[i]的钱。问如何分配这N个人应该付的钱,使N个人出钱的差距最小。

先算出平均每个人需要付多少钱,如果一个人没有那么多钱,就全付,然后记录差距,让后面钱多的人来填补。重复多次这种操作。具体看代码

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 10005;int p,n;int vis[maxn];struct node{    int pay;    int id;    bool operator < (const node& T) const{        if(pay==T.pay) return id>T.id;        return pay<T.pay;    }}tmp[maxn];int ans[maxn];int main(){    int cases;    scanf("%d",&cases);    while(cases--)    {        memset(vis,0,sizeof(vis));        scanf("%d%d",&p,&n);        int nn = n;        long long sum = 0;        for(int i=0;i<n;i++) {scanf("%d",&tmp[i].pay); tmp[i].id = i;sum+=tmp[i].pay;}        if(sum<p){printf("IMPOSSIBLE\n"); continue;}        while(p)        {            int k = p/nn;            int mod = p%nn;            sort(tmp,tmp+n);            int flag = 0;            for(int i=0;i<n;i++)            {                if(vis[tmp[i].id]) continue;                if(tmp[i].pay<=k)                {                    vis[tmp[i].id] = 1;                    p -= tmp[i].pay;                    nn--;                    flag ++;                    ans[tmp[i].id] = tmp[i].pay;                }                else break;            }            if(!flag)            {                for(int i=n-1;i>=0;i--)                {                    if(vis[tmp[i].id]) continue;                    if(mod){                        mod--;                        ans[tmp[i].id] = k+1;                    }                    else                    ans[tmp[i].id] = k;                }                break;            }        }        for(int i=0;i<n-1;i++) printf("%d ",ans[i]);        printf("%d\n",ans[n-1]);    }    return 0;}