例题一
题目链接:https://ac.nowcoder.com/acm/contest/558/C
题意: 给定N个二元组(a1,b1),(a2,b2),…,(aN,bN),请你从中选出恰好K个,使得ai的最小值与bi的最小值之和最大。
请输出ai的最小值与bi的最小值之和
分析:我们可以先按b值从大到小排序,把二元组中的b值按从大到小的次序排序后,依次以第i = k,k + 1···n个数为最后一个数,那么最小的b值肯定是第i对二元组的b值,a值取最大的前k个数中最小的,这个过程可以用优先队列来完成。即在遍历过程中,如果队列的规模大于k,那么把a值最小的元素从队列中移除
参考代码
#include <stdio.h>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
#define N 110000
struct Node {
int a, b;
bool operator < (const Node &u) const {
return b > u.b;
}
};
Node a[N];
int main() {
int n, k;
scanf("%d%d", &n, &k);
for (int i = 0; i < n; ++i) scanf("%d%d", &a[i].a, &a[i].b);
sort(a, a + n);
int res = 0;
priority_queue<int, vector<int>, greater<int> > q;
for (int i = 0; i < n; ++i) {
q.push(a[i].a);
if (q.size() > k) q.pop();
if (q.size() == k) res = max(res, q.top() + a[i].b);
}
printf("%d\n", res);
return 0;
}
例题二
题目链接:http://poj.org/problem?id=3253
题意:给你n个长度为ai的木棒,假设把两个木棒i,j合成一个木棒的花费是ai + aj,问将n个木棒合成一个木棒的最小花费是多少
分析:这是一道特别经典的贪心问题,解决方案是将所有的木棒放入一个优先队列中去,依次取出最小的两根,合并后把新的木棒在放回到优先队列中去
参考代码
#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
#define N 20000
int x;
int main () {
int n;
while (scanf("%d",&n) == 1) {
long long sum = 0;
int cost = 0;
priority_queue<long long, vector<long long>, greater<long long> > q;
for (int i = 0; i < n; ++i) {
scanf("%d",&x);
q.push(x);
}
while (q.size() >= 2) {
long long x,y;
x = q.top(); q.pop();
y = q.top(); q.pop();
sum += x + y;
q.push(x + y);
}
printf("%lld\n",sum);
}
return 0;
}
例题三:题目链接 https://codeforces.com/problemset/problem/462/C
题意:给你n个整数还有一个初始化为0的得分,对于这n个数你首先把计算他们的和,并把和加到得分上,然后把这些数分成两堆,分别求和后加到得分上,如果某一堆只有一个元素那么计算完得分后这个堆就会消息,请你计算得分最大为多少
分析:这个题和上个题目有些类似,只需要每次把值最小的单独放到一个堆就行了,可以使用前缀和方便计算
参考代码
#include <stdio.h>
#include <algorithm>
using namespace std;
#define N 330000
typedef long long ll;
ll a[N], pre[N];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
pre[0] = 0;
for (int i = 1; i <= n; ++i) scanf("%I64d", &a[i]); sort(a + 1, a + n + 1);
for (int i = 1; i <= n; ++i) pre[i] = pre[i - 1] + a[i];
ll res = 0;
for (int i = 0; i < n; ++i) {
// printf("%lld %lld\n", pre[n] - pre[i], a[i]);
res += pre[n] - pre[i];
res += a[i];
}
printf("%I64d\n", res);
}
return 0;
}