POJ_2010 Moo University - Financial Aid 【堆预处理】

一、题面

POJ2010

二、分析

堆预处理

首先可以考虑吧随便取一个点,判断两侧的最小的总费用是多少,然后相加判断是否满足条件。如果直接判断会超时,所以需要用大根堆预处理一下。先看从分数最小的往最大的预处理,先取N/2个相加,并把他们都加入到堆中,先假设这个和值是最大的,然后不断往后扫描的过程中,不断更新大根堆的根值,以及它的和。反向预处理类似。比较容易出错的是选的范围,如果不用那些不可能到的点,可以随意点,但如果需要使用这些点,需要用足够大的值填充。

三、AC代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <queue>
 4 #include <fstream>
 5 #include <iostream>
 6
 7 using namespace std;
 8
 9 const int MAXN = 1e5+4;
10 int N, C, F, ans;
11 struct Node
12 {
13     int score, aid;
14     bool operator<(const Node t)const
15     {
16         return score < t.score;
17     }
18 }Calves[MAXN];
19 int Left[MAXN], Right[MAXN];
20
21 void solve()
22 {
23     priority_queue<int, vector<int>, less<int> > pql, pqr;
24     int i, temp, sum = 0;
25     //正向扫描求最小和,保持大根堆的容量始终为N/2
26     for(i = 0; i < N/2; i++)
27     {
28         sum += Calves[i].aid;
29         Left[i] = 0;
30         pql.push(Calves[i].aid);
31     }
32     for(i; i < C-N/2; i++)
33     {
34         Left[i] = sum;
35         temp = pql.top();
36         if(Calves[i].aid < temp)
37         {
38             pql.pop();
39             sum -= temp;
40             sum += Calves[i].aid;
41             pql.push(Calves[i].aid);
42         }
43     }
44
45     //反向扫描
46     sum = 0;
47     for(i = C-1; i > C-N/2-1; i--)
48     {
49          sum += Calves[i].aid;
50          Right[i] = 0;
51          pqr.push(Calves[i].aid);
52     }
53     for(i; i >= N/2; i--)
54     {
55         Right[i] = sum;
56         temp = pqr.top();
57         if(Calves[i].aid < temp)
58         {
59             pqr.pop();
60             sum -= temp;
61             sum += Calves[i].aid;
62             pqr.push(Calves[i].aid);
63         }
64     }
65
66 }
67
68 int main()
69 {
70     // freopen("input.txt", "r", stdin);
71     // freopen("out.txt", "w", stdout);
72     while(scanf("%d %d %d", &N, &C, &F)!=EOF)
73     {
74         bool flag = false;
75         for(int i = 0; i < C; i++)
76         {
77             scanf("%d %d", &Calves[i].score, &Calves[i].aid);
78         }
79         sort(Calves, Calves+C);
80         solve();
81         for(int i = C-N/2-1; i >= N/2; i--)
82         {
83             if(Right[i] + Left[i] + Calves[i].aid <= F)
84             {
85                 printf("%d\n", Calves[i].score);
86                 flag = true;
87                 break;
88             }
89         }
90         if(!flag)
91         {
92             printf("-1\n");
93         }
94     }
95     return 0;
96 }

原文地址:https://www.cnblogs.com/dybala21/p/10132984.html

时间: 2024-08-25 09:39:27

POJ_2010 Moo University - Financial Aid 【堆预处理】的相关文章

POJ 2010 Moo University - Financial Aid 堆的高级应用 -- 维护最小(最大和)

题目大意:有N头牛,每头牛两个权值,A和B.从这N头牛中选取C头牛,使得: 1.这些牛中A权值的中位数尽量大. 2.这些牛的B权值的和小于题中所给的F 输出这个最大的A权值的中位数:如果没有满足题意的解,就输出-1.值. 思路: 堆有一个神奇的功能.假设上图是一个数组,在B从A到C移动的过程中,利用大根堆可以维护出B在所有位置时,从A到B中选K个值的和的最小值,并在nlogn内得到答案. 方法如下:先把[A,A + K]的元素加入到一个大根堆中,记录它们的总和.之后让B不断向后循环,把B加入到大

poj2010 Moo University - Financial Aid

Moo University - Financial Aid 题意: 一个私立学校的学生要申请奖学金,而学校的金额有限.因此,学校希望在金额不超过F的情况下从C中选得N对数. 给出三个数N,C,F.分别代表在C对数中要取得N对数. 而每对数分别代表成绩,跟申请金额.要求取得N对数中的总金额不超过F的条件下,然取得中间的以为学生的成绩最高.(N为even) 算法分析: 本题有两种解法,一种是用优先队列,一种是二分; 一.利用堆实现 先说堆的实现方法,我们能够现对头尾的N/2进行处理,由于头尾的N/

Moo University - Financial Aid (poj 2010 优先队列 或者 二分)

Language: Default Moo University - Financial Aid Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5551   Accepted: 1663 Description Bessie noted that although humans have many universities they can attend, cows have none. To remedy this p

POJ 2010 Moo University - Financial Aid( 优先队列+二分查找)

POJ 2010 Moo University - Financial Aid 题目大意,从C头申请读书的牛中选出N头,这N头牛的需要的额外学费之和不能超过F,并且要使得这N头牛的中位数最大.若不存在,则输出-1(一开始因为没看见这个,wa了几次). 这个题的第一种做法就是用两个优先队列+贪心. /* * Created: 2016年03月27日 14时41分47秒 星期日 * Author: Akrusher * */ #include <cstdio> #include <cstdl

poj 2010 Moo University - Financial Aid(优先队列(最小堆)+ 贪心 + 枚举)

Description Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short. Not wish

poj2010(Moo University - Financial Aid)优先队列

Description Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short. Not wish

挑战程序设计竞赛2.4习题:Moo University - Financial Aid POJ - 2010

Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short. Not wishing to admit

POJ 2010 - Moo University - Financial Aid 初探数据结构 二叉堆

考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O(1)找到最大/最小值,并能持续维护. 复杂度 push() = O(logn); pop() = O(logn); BinaryHeap() = O(nlogn); 实现 数组下标从1开始的情况下,有 Parent(i) = i >> 1 LChild(i) = i << 1 RChi

poj 2010 Moo University - Financial Aid 大顶堆维护最小和

题意: 有c有牛,从中选(n-1)/2头,使他们的得分中位数最大且需要的资金援助和不超过f. 分析: 堆的运用大顶堆维护最小和. 代码: //poj 2010 //sep9 #include <iostream> #include <queue> #include <algorithm> using namespace std; const int maxN=100024; int dpl[maxN],dpr[maxN]; priority_queue<int&g