Educational Codeforces Round 55 (Rated for Div. 2):C. Multi-Subject Competition
C. Multi-Subject Competition
题目链接:https://codeforces.com/contest/1082/problem/C
题意:
给出n个信息,每个信息包含专业编号以及对应权值,先要求选出一些数量相等的专业(每种专业选的个数相等,不要求每种专业都要选),使对应权值最大。
题解:
一开始想的是枚举选的数量,然后再枚举每种专业从大到小贪心地选,但是时间超了...
其实还有更巧妙地方法,直接考虑每种专业选的个数从1到x对答案的贡献,用一个数组保存这一个贡献就好了。
对于一个专业对答案的贡献用到了最大连续子段和的技巧。
代码如下:
#include <bits/stdc++.h> using namespace std; const int N = 1e5+5; int n,m; vector <int> vec[N]; int main(){ scanf("%d%d",&n,&m); int maxn = 0; int ans=0; for(int i=1;i<=n;i++){ int s,r; scanf("%d%d",&s,&r); vec[s].push_back(r); int tmp=vec[s].size(); maxn=max(maxn,tmp); } for(int i=1;i<=m;i++){ sort(vec[i].begin(),vec[i].end()); reverse(vec[i].begin(),vec[i].end()); } int sum[N]={0}; for(int i=1;i<=m;i++){ int tot=0; int len=vec[i].size(); for(int j=0;j<len;j++){ tot+=vec[i][j]; if(tot>0) sum[j+1]+=tot; else tot=0; } } for(int i=1;i<=maxn;i++) ans=max(ans,sum[i]); cout<<ans; return 0; }
重要的是自信,一旦有了自信,人就会赢得一切。