题意:
有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;
}