Codeforces Round #536 (Div. 2) B. Lunar New Year and Food Ordering(思维)

【题目】

B. Lunar New Year and Food Ordering

【题解】

这道题的主要问题在于,题干比较难读hhh

题意:饭店有n种菜,编号为i∈[1,n]的菜的初始量为ai,价格为bi。有m个客人,每个客人会点d盘编号为t的菜。假设此时的菜的余量为ri,如果ri充足,那么给客人上d盘编号为t的菜,正常消费;如果ri不足,那么剩下的盘数将由剩余最便宜的菜代替,如果价格一样低,编号小的优先被代替;如果ri不足并且没有足够的其他的菜,那么客人会生气的走掉,消费为0并且会拿走之前消费的菜。

思路:能上t就上t,不能上t就最便宜,按菜品消费。如果剩下所有盘数都不足d,那么客人肯定会生气的走掉,并且之后的客人都会生气因为余量为0。问题在于,寻找最便宜需要排序,但是客人直接点编号为t的菜时又不能被排序不然不能直接减掉被消费的菜和计算消费价格。思考了一下,我们只需要按价格和序号对序号排个序即可,然后定义pos存储当前最小的菜品的编号,每次分类讨论即可。

还有一点,第一发wa了,然后改成long long才过的。

我可真是个小机灵鬼儿~  

【代码】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct p{
    ll num;
    ll cc;
}f[100005];
bool cmp(p x,p y)
{
    if(x.cc==y.cc) return x.num<y.num;
    return x.cc<y.cc;
}
int main()
{
    ll n,m; scanf("%I64d%I64d",&n,&m);
    ll sum=0,a[100005],c[100005];
    for(ll i=1;i<=n;i++) scanf("%I64d",&a[i]),sum+=a[i];
    for(ll i=1;i<=n;i++) scanf("%I64d",&c[i]),f[i].num=i,f[i].cc=c[i];
    sort(f+1,f+n+1,cmp);
    ll pos=1;
    while(m--)
    {
        ll t,d;
        scanf("%I64d%I64d",&t,&d);
        if(sum>=d) sum-=d;
        else
        {
            puts("0");
            sum=0;
            continue;
        }
        ll ans=0;
        if(a[t]>=d) ans=d*c[t],a[t]-=d;
        else
        {
            d-=a[t];
            ans+=a[t]*c[t],a[t]=0;
            while(d)
            {
                while(a[f[pos].num]==0) pos++;
                ll poss=f[pos].num;
                if(a[poss]>=d)
                {
                    a[poss]-=d,ans+=d*c[poss];
                    d=0;
                }
                else
                {
                    ans+=a[poss]*c[poss];
                    d-=a[poss];
                    a[poss]=0;
                }
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值