2020牛客多校第八场K-Kabaleo Lite

Kabaleo Lite

Kabaleo Lite

题意

T组样例,每组样例给定n种菜,给出每种菜的盈利数,数量,顾客只能从第一道菜吃起,你可以决定顾客吃到哪。在顾客人数最多的条件下,盈利最多。输出盈利数。

3
2 -1 3 这是盈利数
3 2 1 这是菜数量
所以第一个客人2+(-1)+3=4
第二个2
第三个2
客人数3
最大盈利是8

思路

对a数组做前缀和,下标从0~i,取菜品数量最小值,以前缀和为第一关键字,数量为第二关键字,下标为第三关键字。
这样的话,对这个含有三个关键字的数据排序,如果这个数据的第三关键字(即下标)比前一个小,那么必定不能计数,因为已经被后面那个更大的数给用完了;如果这个数据的第二关键字(即数量)比前一个小,也必不可能计数,因为已经被后面那个更大的数给用完了。

注意题目数据范围可能超过long long,要用__int128

代码

#include<bits/stdc++.h>
#define ll __int128
#define pii pair<ll,pair<ll,ll> >
using namespace std;

inline __int128 read(){
    __int128 x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

inline void print(__int128 x){
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9)
        print(x/10);
    putchar(x%10+'0');
}

const ll maxn=1e5+10;
ll a[maxn],b[maxn],c[maxn];
priority_queue<pii> q;

int main()
{

    ll t;
    t=read();
    ll kk=1;
    while(t--){
        ll n;
        n=read();
        for(ll i=0;i<n;i++) a[i]=read();
        for(ll i=0;i<n;i++) b[i]=read();
        for(ll i=0;i<n;i++){
            if(i) c[i]=c[i-1]+a[i];
            else c[i]=a[i];
        }
        __int128 ans=0;
        ll bb=b[0];
        for(ll i=0;i<n;i++){
            bb=min(bb,b[i]);
            q.push({c[i],{bb,i}});
        }
        ll cnt=0,pos=n;
        while(!q.empty()){
            ll x=q.top().first,y=q.top().second.first,z=q.top().second.second;
            q.pop();
            if(y<=cnt||pos<=z) continue;
            ans+=x*(y-cnt);
            cnt=y;
            pos=z;
        }
        cout<<"Case #";
        print(kk++);
        cout<<": ";
        print(b[0]);
        cout<<" ";
        print(ans);
        cout<<endl;
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值