题目链接:Codeforces - Multi-Subject Competition
显然我们人肯定是从大往小选。(忘了排序,傻傻地一直WA)。
然后我们枚举每一组选多少个人即可。
因为可能会有一组人特别多,然后我们就会n*m枚举,TLE,所以我们先按人数排序。
这样只要这一组人不够,那么后面肯定也不够,直接break
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,m,s[N],r[N],res,tmp,vis[N],sum,mx;
struct node{int id,cnt;}t[N];
vector<int> v[N];
int cmp(node a,node b){return a.cnt>b.cnt;}
signed main(){
cin>>n>>m;
for(int i=1;i<=m;i++) t[i].id=i;
for(int i=1;i<=n;i++) scanf("%d %d",&s[i],&r[i]),t[s[i]].cnt++;
sort(t+1,t+1+m,cmp);
for(int i=1;i<=m;i++) vis[t[i].id]=i;
for(int i=1;i<=n;i++) v[vis[s[i]]].push_back(r[i]);
for(int i=1;i<=m;i++) sort(v[i].begin(),v[i].end(),greater<int>());
for(int i=1;i<=m;i++) for(int j=1;j<v[i].size();j++) v[i][j]+=v[i][j-1];
for(int i=1;i<=n;i++){
tmp=0;
for(int j=1;j<=m;j++){
if(i>v[j].size()) break;
if(v[j][i-1]>0) tmp+=v[j][i-1];
}
res=max(res,tmp);
}
cout<<res;
return 0;
}