Educational Codeforces Round 55 (Rated for Div. 2)-C. Multi-Subject Competition

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/84670211

地址:http://codeforces.com/contest/1082/problem/C

思路:前缀和,将同一个项目的得分按照由大到小排序,再将每个项目按照得分个数由大到小排序,遍历项目,用pre[i]表示每个项目选i个分数的最大价值,遍历k项目时,用bb[i]保存前缀和,在将为正值的加入pre[i]中,同时ans保存最大pre[i]即可

Code:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long LL; 

const int MAX_N=1e5+5;
struct node{
	int x;
	int id;
	bool operator<(const node &p)const{
		return x>p.x;
	}
};
int n,m;
node a[MAX_N];
vector<LL> d[MAX_N];
LL pre[MAX_N],bb[MAX_N];

bool cmp(const LL &a,const LL &b) {
	return a>b;
}

int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	int x,y;
	for(int i=0;i<n;++i)
	{
		cin>>x>>y;
		d[x].push_back(y);
	}
	for(int i=1;i<=m;++i)
	{
		a[i].id=i;	a[i].x=d[i].size();
		if(a[i].x)	sort(d[i].begin(),d[i].end(),cmp);
	}
	sort(a+1,a+m+1);
	LL ans=0;
	for(int i=1;i<=m;++i)
	{
		int id=a[i].id,s=a[i].x;
		if(!s)	break;
		bb[0]=d[id][0];
		for(int j=1;j<s;++j)
			bb[j]=bb[j-1]+d[id][j];
		for(int j=0;j<s;++j)
		{
			if(bb[j]<0)	break;
			pre[j]+=bb[j];
			ans=max(ans,pre[j]);
		}
	}
	cout<<ans<<endl;
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/84670211