Financial Aid 贪心+优先队列

题目大意:有C头牛,每头牛都有相应的分数和需求,要求在这C头牛中选出N头,使得这N头牛中的分数的中位数达到最大,且需求之和小于等于F

解题思路:先按成绩排序 再用两个数组保留最小需求之和 left数组保留第i个位置左边的 N/2个最小需求之和 right数组保留第i个位置右边的 N/2个最小需求之和 如何保留最小的需求之和呢,扫描两遍(左右),用优先队列保留N / 2个最小需求 最后只需要判断一下 left[i] + right[i] + 第i头牛的需求 <= F就可以了

;ll;struct Cows{ll score, aid;}cow[maxn];int N, C;ll F, left[maxn], right[maxn];bool cmp(const Cows a, const Cows b) {return a.score < b.score;}void solve() {sort(cow, cow + C, cmp);for(int i = 0; i < C; i++)left[i] = right[i] = 0;priority_queue<ll> pq;ll sum1 = 0;for(int i = 0; i < C; i++) {if(i < N / 2) {pq.push(cow[i].aid);sum1 += cow[i].aid;continue;}left[i] = sum1;if(cow[i].aid >= pq.top())continue;sum1 -= pq.top();pq.pop();sum1 += cow[i].aid;pq.push(cow[i].aid);}while(!pq.empty())pq.pop();sum1 = 0;for(int i = C – 1; i >= 0; i–) {if(i > C – 1 – N / 2) {sum1 += cow[i].aid;pq.push(cow[i].aid);continue;}right[i] = sum1;if(cow[i].aid >= pq.top())continue;sum1 -= pq.top();pq.pop();sum1 += cow[i].aid;pq.push(cow[i].aid);}ll ans = -1;for(int i = N / 2; i <= C – 1 – N / 2; i++)if(left[i] + right[i] + cow[i].aid <= F)ans = cow[i].score;printf(“%lld\n”, ans);}int main(){while(scanf(“%d%d%lld”,&N, &C, &F) != EOF) {for(int i = 0; i < C; i++)scanf(“%lld%lld”, &cow[i].score, &cow[i].aid);solve();}return 0;}

,快忘了那些不高兴的事吧!你看就连今天的阳光都如此明媚灿烂,

Financial Aid 贪心+优先队列

相关文章:

你感兴趣的文章:

标签云: