POJ 2010 Moo University - Financial Aid (优先队列/二分答案)
来源:互联网 发布:统计表制作软件 编辑:程序博客网 时间:2024/05/22 13:12
题目大意:
从c(<=1e5)个物品中选出n(奇数 <= 19,999)个物品,使得这n个物品的价值中位数尽量高,且总价格不超过f (<= 2,000,000,000)。
做法1:
- 把物品按价值排序
- half表示n/2向下取整
- low[i]表示前i - 1个物品中价格最小的half个物品的价格和
- hei[i]表示i之后的物品中价格最小的half个物品的价格和
- low和hei可用优先队列维护
- 枚举中间物品即可
代码
#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>using namespace std;const int maxc = 1e5 + 10;pair<int, int>p[maxc];long long low[maxc], hei[maxc];int main(){ int n, c, f; scanf("%d%d%d", &n, &c, &f); int half = n / 2; for (int i = 0 ; i < c ; i++) scanf("%d%d", &p[i].first, &p[i].second); sort(p, p + c); { long long sum = 0; priority_queue<long long>q; for (int i = 0 ; i < half ; i++) { q.push(p[i].second); sum += p[i].second; low[i] = 0x7fffffff; } for (int i = half ; i < c ; i++) { low[i] = sum; q.push(p[i].second); sum += p[i].second - q.top(); q.pop(); } } { long long sum = 0; priority_queue<long long>q; for (int i = c - 1 ; i >= c - half ; i--) { q.push(p[i].second); sum += p[i].second; hei[i] = 0x7fffffff; } for (int i = c - half - 1 ; i >= 0 ; i--) { hei[i] = sum; q.push(p[i].second); sum += p[i].second - q.top(); q.pop(); } } int ans = -1; for (int i = c - 1 ; i >= 0 ; i--) if (hei[i] + low[i] + p[i].second <= f) { ans = p[i].first; break; } printf("%d\n", ans); return 0;}
做法2:
- 保存两组信息,一组物品按价值排序,另一组按价格排序
- 二分中间物品的价格
- 检查答案是否合法
代码
#include <cstdlib>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;const int maxn = 1e5 + 10;struct stu{ int first, second, id;}p[maxn], s[maxn];bool cmp1(const stu &a, const stu &b){return a.first < b.first;}bool cmp2(const stu &a, const stu &b){return a.second < b.second;}int main(){ int n, c ,f; scanf("%d%d%d", &n, &c, &f); int half = n / 2; for (int i = 0 ; i < c ; i++) scanf("%d%d", &p[i].first, &p[i].second); sort(p, p + c, cmp1); for (int i = 0 ; i < c ; i++) p[i].id = i; memcpy(s, p, sizeof(stu) * c); sort(p, p + c, cmp2); int l = 0, r = c, ans = -1; while (l < r) { int m = (l + r) / 2; int lc = 0, rc = 0, sum = s[m].second; for (int i = 0 ; i < c ; i++) { if (lc < half && p[i].id < s[m].id && sum + p[i].second <= f) { sum += p[i].second; lc++; }else if (rc < half && p[i].id > s[m].id && sum + p[i].second <= f) { sum += p[i].second; rc++; } } if (lc < half && rc < half) { ans = -1; break; } else if (lc < half) l = m + 1; else if (rc < half) r = m; else{ ans = s[m].first; l = m + 1; } } printf("%d\n", ans); return 0;}
0 0
- POJ 2010 Moo University - Financial Aid (优先队列/二分答案)
- Moo University - Financial Aid (poj 2010 优先队列 或者 二分)
- POJ 2010 - Moo University - Financial Aid (优先队列)
- POJ 2010 Moo University - Financial Aid (优先队列)
- POJ 2010 Moo University - Financial Aid(优先队列)
- POJ 2010 - Moo University - Financial Aid(优先队列)
- POJ - 2010 Moo University - Financial Aid 贪心+优先队列
- poj 2010 Moo University - Financial Aid 优先队列
- [POJ 2010]Moo University - Financial Aid[优先队列]
- Poj 2010 Moo University - Financial Aid【优先队列+神技巧】
- POJ 2010 Moo University - Financial Aid 优先队列
- POJ 2010 Moo University - Financial Aid(优先队列or二分搜索—最大化K大值)
- Moo University - Financial Aid - POJ 2010 二分
- POJ - 2010 Moo University - Financial Aid(二分)
- POJ 2010 Moo University - Financial Aid (二分搜索)
- poj 2020Moo University - Financial Aid(优先队列)
- POJ2010 Moo University - Financial Aid 优先队列
- [优先队列] POJ2010 Moo University - Financial Aid
- 【历届试题】矩阵翻硬币
- 在嵌入式设备上设定ftp服务器的家目录
- android CoordinatorLayout使用
- 20160303线性模型.md
- 重置树莓派的密码
- POJ 2010 Moo University - Financial Aid (优先队列/二分答案)
- jQuery总结
- 简化脚本
- Linux系统运维/正则表示法/6-1
- 项目2:就拿胖子说事---(1)计算并输出标准体重
- LeetCode : 3Sum [java]
- Java 抽象类与接口区别
- fzu2092收集水晶 记忆化搜索
- wordpress 3步历史图片加水印