Educational Codeforces Round 55 (Rated for Div. 2) C. Multi-Subject Competition (实现,贪心,排序)

C. Multi-Subject Competition
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
A multi-subject competition is coming! The competition has m different subjects participants can choose from. That‘s why Alex (the coach) should form a competition delegation among his students.

He has n candidates. For the i-th person he knows subject si the candidate specializes in and ri — a skill level in his specialization (this level can be negative!).

The rules of the competition require each delegation to choose some subset of subjects they will participate in. The only restriction is that the number of students from the team participating in each of the chosen subjects should be the same.

Alex decided that each candidate would participate only in the subject he specializes in. Now Alex wonders whom he has to choose to maximize the total sum of skill levels of all delegates, or just skip the competition this year if every valid non-empty delegation has negative sum.

(Of course, Alex doesn‘t have any spare money so each delegate he chooses must participate in the competition).

Input
The first line contains two integers n and m (1≤n≤105, 1≤m≤105) — the number of candidates and the number of subjects.

The next n lines contains two integers per line: si and ri (1≤si≤m, ?104≤ri≤104) — the subject of specialization and the skill level of the i-th candidate.

Output
Print the single integer — the maximum total sum of skills of delegates who form a valid delegation (according to rules above) or 0 if every valid non-empty delegation has negative sum.

Examples
inputCopy
6 3
2 6
3 6
2 5
3 5
1 9
3 1
outputCopy
22
inputCopy
5 3
2 6
3 6
2 5
3 5
1 11
outputCopy
23
inputCopy
5 2
1 -1
1 -5
2 -1
2 -1
1 -10
outputCopy
0
Note
In the first example it‘s optimal to choose candidates 1, 2, 3, 4, so two of them specialize in the 2-nd subject and other two in the 3-rd. The total sum is 6+6+5+5=22.

In the second example it‘s optimal to choose candidates 1, 2 and 5. One person in each subject and the total sum is 6+6+11=23.

In the third example it‘s impossible to obtain a non-negative sum.

题意:
有一个竞赛,有m个科目,现在有n个学生,每一个学生只对一个科目有一个水平值。现在要求选出一些学生,要求这些学生参加的科目中,每一个科目的学生数量应该相同。 现在问你选可以选择出的最大水平值sum和是多少?
思路:

把学生信息按照擅长的科目加入到一个vector中,然后对每一个科目的Vector进行排序,维护一个数组 mx[i] 代表所有科都(如果人数小于i就贡献为0,可以忽略)选择了 i 个人的水平sum和是多少。因为有负的水平,所以我们在处理的时候,如果一个项目中学生的水平sum和小于0的时候,就结束这个项目的维护,以此保证答案最优。

细节见代码:

#include<bits/stdc++.h>
using namespace std;

#define fore(i, l, r) for(int i = int(l); i < int(r); i++)
#define sz(a) int((a).size())

int n, m;
vector<int> s, r;

inline bool read() {
    if(!(cin >> n >> m))
        return false;
    s.assign(n, 0);
    r.assign(n, 0);

    fore(i, 0, n) {
        assert(cin >> s[i] >> r[i]);
        s[i]--;
    }
    return true;
}

vector< vector<int> > subs;

inline void solve() {
    subs.assign(m + 1, vector<int>());

    fore(i, 0, n)
        subs[s[i]].push_back(r[i]);

    fore(id, 0, sz(subs)) {
        sort(subs[id].begin(), subs[id].end());
        reverse(subs[id].begin(), subs[id].end());
    }

    vector<int> mx(n + 5, 0);
    fore(id, 0, sz(subs)) {
        int curSum = 0;
        fore(i, 0, sz(subs[id])) {
            curSum += subs[id][i];
            if(curSum < 0)
                break;

            mx[i + 1] += curSum;
        }
    }

    cout << *max_element(mx.begin(), mx.end()) << endl;
}

int main() {
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
    int tt = clock();
#endif
    cout << fixed << setprecision(15);

    if(read()) {
        solve();

#ifdef _DEBUG
        cerr << "TIME = " << clock() - tt << endl;
        tt = clock();
#endif
    }
    return 0;
}

原文地址:https://www.cnblogs.com/qieqiemin/p/11185074.html

时间: 2024-10-06 09:17:38

Educational Codeforces Round 55 (Rated for Div. 2) C. Multi-Subject Competition (实现,贪心,排序)的相关文章

Educational Codeforces Round 55 (Rated for Div. 2)

Educational Codeforces Round 55 (Rated for Div. 2) 链接 A Vasya and Book 傻逼题..注意判边界. #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<set> #include<map> #include<vector> #include<cm

Educational Codeforces Round 55 (Rated for Div. 2) C. Multi-Subject Competition 【vector 预处理优化】

传送门:http://codeforces.com/contest/1082/problem/C C. Multi-Subject Competition time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A multi-subject competition is coming! The competition has mm 

Codeforces 1082 C. Multi-Subject Competition-有点意思 (Educational Codeforces Round 55 (Rated for Div. 2))

C. Multi-Subject Competition time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A multi-subject competition is coming! The competition has mm different subjects participants can choose from.

[Educational Codeforces Round 55 (Rated for Div. 2)][C. Multi-Subject Competition][时间复杂度]

https://codeforc.es/contest/1082/problem/C 题目大意:有m个类型,n个人,每个人有一个所属类型k和一个能力v,要求所选的类型的人个数相等并且使v总和最大(n,m<=1e5) 题解:用vector存下每种类型的各个v并且每种类型根据v按从大到小排序,然后处理出每种类型的前缀和,然后扫每种类型的所有前缀和,如果该类型在i处的前缀和大于0,则相应的ans[i]加上这个类型在i处的前缀和,最后求出max(ans[i])(1<=i<=n)即可. 注意:这题

Codeforces 1082 A. Vasya and Book-题意 (Educational Codeforces Round 55 (Rated for Div. 2))

A. Vasya and Book time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Vasya is reading a e-book. The file of the book consists of nn pages, numbered from 11 to nn. The screen is currently disp

Codeforces 1082 D. Maximum Diameter Graph-树的直径-最长链-构造题 (Educational Codeforces Round 55 (Rated for Div. 2))

D. Maximum Diameter Graph time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Graph constructive problems are back! This time the graph you are asked to build should match the following proper

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

这道题比赛时候没做出来,下来一看才发现是排序傻逼题. 把每个偏好的人做成一个vector,从大到小排序,做一个前缀和.然后将每种人数做一个桶,在桶里装每种科目选择人数为i的时候分数总和. 遍历每一维vector,把各个位置上面的vector加到sum数组中,最后sum数组里面挑出最大值. #include<bits/stdc++.h> using namespace std; typedef long long ll; vector<int> vec[100010];//vecto

Educational Codeforces Round 55 (Rated for Div. 2) B. Vova and Trophies

传送门 https://www.cnblogs.com/violet-acmer/p/10035971.html 题意: Vova有n个奖杯,这n个奖杯全部是金奖或银奖,Vova将所有奖杯排成一排,你最多可以交换其中两个奖杯,求最大的连续的金奖杯个数. 题解: 思路: 求出连续的金奖杯位置,找出每两个相邻的连续的金奖杯所能够形成的最大的连续的金奖杯的个数,输出最大值. 相关变量解释: 1 int n; 2 char trophy[maxn]; 3 struct Node 4 { 5 int l,

Educational Codeforces Round 36 (Rated for Div. 2)

Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree You are given a tree T consisting of n vertices. A number is written on each vertex; the number written on vertex i is ai. Let's denote the function I(x,?y) as the differ