POJ 2010 Moo University - Financial Aid
http://poj.org/problem?id=2010
贪心策略
按score从大到小排列
枚举i位置
让i以前的cow中选N / 2个的aid和最小 l_aid[]
同理让i以后的cow中选N / 2的aid 和最小r_aid[]
正向一次求得l_aid[] 每次入队优先队列吐出最大的 算出前N/2的money
如果que.size() < N / 2直接入队
同理方向一次求得r_aid[]
注意小细节很容易出错
因为记录前N / 2个的和 吧第N / 2个也加了进去 WA了两个小时没查出来 哎
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <queue> 5 #include <algorithm> 6 7 #define INF 2000000007 8 using namespace std; 9 10 typedef pair<int,int> P; 11 12 P cow[100007]; 13 int r_aid[100007], l_aid[100007]; 14 15 bool cmp(P a, P b) 16 { 17 return a.second > b.second; 18 } 19 20 priority_queue<P> ql, qr;//大根堆 按钱 从大到小排 21 int main() 22 { 23 int N, C; 24 int F; 25 int money = 0; 26 freopen("in.txt", "r", stdin); 27 cin >> N >> C >> F; 28 for (int i = 0; i < C; i++) 29 { 30 int score, aid; 31 scanf("%d%d", &score, &aid); 32 //cin >> score >> aid; 33 cow[i] = P(aid, score); 34 } 35 sort(cow, cow+C, cmp);//按score从大到小排 36 for (int i = 0; i < C; i++)//正扫一遍求左边 37 { 38 if (ql.size() < (N / 2) || i == 0)//避免N为1 的情况 39 { 40 ql.push(cow[i]); 41 money += cow[i].first; 42 } 43 else 44 { 45 l_aid[i] = money;//前N / 2的money情况 46 money += cow[i].first; 47 ql.push(cow[i]); 48 money -= ql.top().first; 49 ql.pop(); 50 } 51 //l_aid[i] = money;//错误确实出在这里 这里前 N / 2个把自己加进去了 52 } 53 money = 0; 54 for (int i = C-1; i >= 0; i--)//反扫一遍求右边 55 { 56 if (C - i - 1 < N / 2 || i == C-1) 57 { 58 qr.push(cow[i]); 59 money += cow[i].first; 60 } 61 else 62 { 63 r_aid[i] = money; 64 money += cow[i].first; 65 qr.push(cow[i]); 66 money -= qr.top().first; 67 qr.pop(); 68 } 69 //r_aid[i] = money;已经重新算过 money了 出现了错误 70 } 71 for (int i = 0+N / 2; i <= C - 1 - N / 2; i++)//从左往右找到第一个 小于l_aid[i]+r_aid[i]的 72 { 73 if(l_aid[i] + r_aid[i] + cow[i].first <= F) 74 { 75 cout << cow[i].second << endl; 76 return 0; 77 } 78 } 79 cout << -1 << endl; 80 return 0; 81 }