题意
N个苹果,A和B对每个苹果有一个出价ai,bi。每个苹果只能被卖给一个人,A最多买A个苹果,B最多买B个。求最多能卖多少钱。
A+B<=N<=1e5
ai,bi<=1e5
题解
按照ai排序,先由A买苹果1..A个。1..A必然会被买(若有苹果未被买,则可以让A少买一个后面的苹果使总价值最大)。那么对于剩下的苹果,先由B选前B大的。枚举苹果A+1..B:若此苹果没人买,则可以让B放弃当前最小苹果;若已被B买了,则让B放弃此苹果,而买1..A中bi-ai最大的苹果。过程记录最大值即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 struct node 5 { 6 int a, b; 7 }p[100010]; 8 9 bool cmp(node x, node y) 10 { 11 if (x.a == y.a) 12 return x.b > y.b; 13 else 14 return x.a > y.a; 15 } 16 17 set<pair<int, int > > aa, bb; 18 19 int main() 20 { 21 int n, A, B; 22 scanf("%d%d%d", &n, &A, &B); 23 for (int i = 1; i <= n; ++i) 24 { 25 scanf("%d", &p[i].a); 26 if (p[i].a < 0) 27 p[i].a = 0; 28 } 29 for (int i = 1; i <= n; ++i) 30 { 31 scanf("%d", &p[i].b); 32 if (p[i].b < 0) 33 p[i].b = 0; 34 } 35 sort(p + 1, p + 1 + n, cmp); 36 long long m(0), ans(0); 37 for (int i = 1; i <= A; ++i) 38 { 39 aa.insert({p[i].b - p[i].a, i}); 40 m += p[i].a; 41 } 42 for (int i = A + 1; i <= A + B; ++i) 43 { 44 bb.insert({p[i].b, i}); 45 m += p[i].b; 46 } 47 for (int i = A + B + 1; i <= n; ++i) 48 { 49 m += p[i].b; 50 bb.insert({p[i].b, i}); 51 m -= bb.begin()->first; 52 bb.erase(bb.begin()); 53 } 54 ans = m; 55 for (int i = A + 1; i <= A + B; ++i) 56 { 57 if (bb.find({p[i].b, i}) == bb.end()) 58 { 59 m -= bb.begin()->first; 60 bb.erase(bb.begin()); 61 } 62 else 63 { 64 m -= p[i].b; 65 bb.erase({p[i].b, i}); 66 } 67 m += p[i].a; 68 aa.insert({p[i].b - p[i].a, i}); 69 m += (--aa.end())->first; 70 aa.erase(--aa.end()); 71 ans = max(ans, m); 72 } 73 printf("%lld\n", ans); 74 75 return 0; 76 }