18873 团队实力

解题思路:团队成员中必然有一个人限定值最小。因此枚举这个限定值最小的人。

先将所有成员按限定值从大到小排队,然后依次枚举限定值i,枚举时用一个小根堆(优先队列)来存储1...i-1中能力的大值,当枚举到i成员时,根据i成员的限制,将堆中超出限定人数的成员移除出去。那么移除的元素是否后面还会用到呢?因为限定值从大到小,所以i之后的元素限定值会更小,这样就能确定移除不会再被用到。

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
struct node
{
    int v,s;
    bool operator <(const node y)const
    {
        return v>y.v;
    }
} a[100005];
int cmp(node x,node y) //cmp用作排序
{
    return x.s>y.s;
}
priority_queue<node>pq;
int main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    //freopen("5.in","r",stdin);
    //freopen("5.out","w",stdout);
    int i,j,n;
    ll sum=0,maxn=0;
    cin>>n;
    for(i=1; i<=n; i++)
        cin>>a[i].v>>a[i].s;
    sort(a+1,a+n+1,cmp);/**< 先按照s排序,先做限制数大的 */
    for(i=1; i<=n; i++)
    {
        pq.push(a[i]);
        sum+=a[i].v;/**< 越往后限制越严格,队列存储的一定满足s[i] */
        while(pq.size()>a[i].s) /**< 根据s[i],把值最小的踢出去 */
        {
            sum-=pq.top().v;
            pq.pop();
        }
        maxn=max(maxn,sum);
    }
    cout<<maxn;
    return 0;
}

其实在用优先队列处理数据时不需要存储限定值。只存储能力值即可。下述代码用set取代优先队列。

#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
pair<int,int>p[100005];
int main()
{
    ios::sync_with_stdio(0);
    multiset<int>st;
    long long  n,i,j,sum=0,ans=0;
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>p[i].second>>p[i].first;
    sort(p+1,p+n+1);
    for(i=n;i>=1;i--)
    {
        while(st.size()>=p[i].first)
            sum-=*st.begin(),st.erase(st.begin());
        sum+=p[i].second;
        st.insert(p[i].second);
        ans=max(ans,sum);
    }
    cout<<ans;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值