CodeForces 1082 C.Multi-Subject Competition(前缀和+思维)

题意:

有n个人,m个项目,每个人有可选的科目si,和能力值ri,
现在每个项目要么选要么不选的,选的项目要求人数相同,问你选中的项目的最大能力总和是多少
n,m<=2e5

思路:

容易想到先给每种科目从大到小排序,然后枚举选择的人数

用ans(x)表示人数为x的答案
计算ans(x)需要遍历m类的每一类,如果某一类的前缀和sum(x)大于0则累加
即ans(x)=sum1(x)+sum2(x)…
需要遍历一遍累加,对于这题数据范围显然吃不消

可以反过来想想,把所有sum(x)加到ans(x)
计算前缀和的时候如果当前前缀和sum(k)大于0,则累加至答案ans(k),省去了一层遍历
最后对所有ans取max就是答案

code:

#include<bits/stdc++.h>
using namespace std;
const int maxm=1e5+5;
vector<int>g[maxm];
int ans[maxm];
bool cmp(int a,int b){
    return a>b;
}
signed main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int s,v;
        cin>>s>>v;
        g[s].push_back(v);
    }
    int malen=0;
    for(int i=1;i<=m;i++){
        sort(g[i].begin(),g[i].end(),cmp);
        int len=g[i].size();
        malen=max(malen,len);
        int sum=0;
        for(int j=0;j<len;j++){
            sum+=g[i][j];
            if(sum>0)ans[j+1]+=sum;
            else break;
        }
    }
    int res=0;
    for(int i=1;i<=malen;i++){
        res=max(res,ans[i]);
        if(ans[i]==0)break;
    }
    cout<<res<<endl;
    return 0;
}
发布了430 篇原创文章 · 获赞 36 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/104401231