【2019杭电多校第八场1011=HDU6667】Roundgod and Milk Tea(贪心)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6667

题目:


t≤25个样例,n≤1e6个班级,每个班级有a_i个人,做了b_i杯奶茶,每个人只能喝一杯奶茶且不能喝自己班做的奶茶。

问最多有多少学生能喝到奶茶?

input1:

1

2

3 4

2 1

output2:

3

input2:

1
4
4 2
3 5
3 4
2 1

output2:

12

解题思路:


按照b_i从大到小排序,对于奶茶数目,按照贪心的思想,一定要先把数目最大的分配给其他人,那么分配给谁呢?做出的奶茶数目少的班级应该最后再安排哪些人喝他们的奶茶(当然可能最后没有人被分配到这些班级),这样才能使没被喝的奶茶数目最少。所以先把b_i小的班级的人分配给b_i大的班级去喝奶茶。

这样处理完之后需要考虑最后处理到的那个班级是否还有奶茶,因为那个班级的人不能和自己班的奶茶,对n=1这种情况特判。

 

ac代码:


#include <bits/stdc++.h>
#define maxn 1000005
using namespace std;
typedef long long ll;
struct node{
    int a, b;
    friend bool operator < (node aa, node bb)
    {
        return aa.b > bb.b;
    }
}c[maxn];
ll suma, sumb;
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    int t, n;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        suma = sumb = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d %d", &c[i].a, &c[i].b);
            suma += c[i].a;
            sumb += c[i].b;
        }
        if(n == 1)
        {
            printf("0\n");
            continue;
        }
        sort(c+1, c+1+n);
        int pb = 1, pa = n;
        ll ans = 0;
        while(pb <=n && pa >= 1)
        {
            if(pb == pa)
            {
                pa--;
                continue;
            }
            if(c[pa].a < c[pb].b)
            {
                int x = c[pa].a;
                ans += x;
                suma -= x; sumb -= x;
                c[pb].b -= x;
                c[pa].a = 0;
                pa--;
            }
            else if(c[pa].a > c[pb].b)
            {
                int x = c[pb].b;
                ans += x;
                suma -= x; sumb -= x;
                c[pb].b = 0;
                c[pa].a -= x;
                pb++;
            }
            else
            {
                int x = c[pb].b;
                ans += x;
                suma -= x; sumb -= x;
                c[pb].b = 0;
                c[pa].a = 0;
                pb++;
                pa--;
            }
        }
        if(pa == 0) pa++;
        if(pa >= 1 && c[pa].b != 0)  ans += min(suma, sumb - c[pa].b);
        else ans += min(suma, sumb);
        printf("%lld\n", ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值