codeforces+C. Multi-Subject Competition+技巧
阿新 • • 發佈:2019-01-01
題目連結:http://codeforces.com/problemset/problem/1082/C
題目大意:
有n個人,m個競賽,(1≤n≤10^5, 1≤m≤10^5)
每個人熟悉一個競賽si,並且熟悉的本領為ri(ri可以為負)
現在讓你選擇去參加競賽的人,對應選擇的要求:對於有人去的這些競賽,去的人數必須相同,有的競賽可以沒人去。
問你去的人的本領總和最大是多少?
思路:
但是複雜度為O(n*m)。
但是可以用邊求字首和邊求C[i]陣列,複雜度為O(n)
for(int i=1;i<=m;i++) { sort(v[i].begin(), v[i].end(), ru);//排序 long long s=0; for(int j=0;j<v[i].size();j++) { s+=v[i][j]; if(s>0)/*如果字首和>0那麼選擇j個人,一定會選這個學科,所以c[j]+=s;*/ c[j]+=s; else break; } }
思路:一個好的技巧
#include<bits/stdc++.h> #define ll long long using namespace std; const int N = 100005; vector<int> v[N]; ll c[N]; int ru(int a, int b){return a>b;} int main() { fill(c, c+N, 0); int n, m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { int x, y; scanf("%d%d",&x, &y); v[x].push_back(y); } for(int i=1;i<=m;i++) { sort(v[i].begin(), v[i].end(), ru);//排序 long long s=0; for(int j=0;j<v[i].size();j++) { s+=v[i][j]; if(s>0)/*如果字首和>0那麼選擇j個人,一定會選這個學科,所以c[j]+=s;*/ c[j]+=s; else break; } } cout<<*max_element(c, c+100002)<<endl; return 0; }