【题解】喷泉
作者:互联网
为什么我会用二分
思路
我们可以先将金币喷泉和钻石喷泉分离出来,进行分类讨论。
- 一个喷泉是金币喷泉,另一个是钻石喷泉:于是我们可以考虑贪心,即使用在花费内,美丽度最大的喷泉。如果说有一类喷泉中的所有喷泉的价格都超出了花费,那么这种情况就无解。
- 两个都是金币喷泉:首先我们可以考虑按花费从小到大排序,对于每一个喷泉 &i&,将它与 \(1 \to i - 1\) 的所有喷泉配对,取美丽度的最大值,但这样一定会超时。所以我们考虑想这一件事情,由于我们排了序,如果 \(p - 1 (1 \leq p \leq i - 1)\) 和 \(i\) 的花费和大于了本金,即不能同时修建这两个喷泉,那么 \(p\) 和 \(i\) 也不能同时修建,即它具有单调性,所以我们可以考虑二分,对于最大值进行预处理即可。
- 两个都是钻石喷泉:同理。
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1e5 + 5;
int n, c, d, ans, res;
struct Node {
int val, cost;
bool operator < (const Node o) {
return cost < o.cost;
}
} a[MAXN], b[MAXN];
int pre[MAXN];
int tot1, tot2;
int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while ('0' <= ch && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
int main() {
scanf("%d %d %d", &n, &c, &d);
for (int i = 1; i <= n; i++) {
int val, cost;
char ch;
scanf("%d %d %c", &val, &cost, &ch);
if (ch == 'C' && cost <= c)
a[++tot1].val = val, a[tot1].cost = cost;
else if (ch == 'D' && cost <= d)
b[++tot2].val = val, b[tot2].cost = cost;
}
sort(a + 1, a + tot1 + 1);
sort(b + 1, b + tot2 + 1);
int res1 = 0, res2 = 0;
int flag = 0;
for (int i = 1; i <= tot1; i++)
if (a[i].cost <= c) {
res1 = max(res1, a[i].val);
if (!flag)
flag++;
}
for (int i = 1; i <= tot2; i++)
if (b[i].cost <= d) {
res2 = max(res2, b[i].val);
if (flag == 1)
flag++;
}
if (flag == 2)
ans = max(res1 + res2, ans);
for (int i = 1; i <= tot1; i++)
pre[i] = max(pre[i - 1], a[i].val);
for (int i = 2; i <= tot1; i++) {
int l = 1, r = i - 1, p = 1;
while (l <= r) {
int mid = (l + r) >> 1;
if (a[mid].cost <= c - a[i].cost)
p = mid, l = mid + 1;
else
r = mid - 1;
}
if (a[i].cost + a[p].cost <= c)
ans = max(ans, a[i].val + pre[p]);
}
for (int i = 1; i <= tot2; i++)
pre[i] = max(pre[i - 1], b[i].val);
for (int i = 2; i <= tot2; i++) {
int l = 1, r = i - 1, p = 1;
while (l <= r) {
int mid = (l + r) >> 1;
if (b[mid].cost <= d - b[i].cost)
p = mid, l = mid + 1;
else
r = mid - 1;
}
if (b[i].cost + b[p].cost <= d)
ans = max(ans, b[i].val + pre[p]);
}
printf("%d", ans);
return 0;
}
标签:ch,int,题解,喷泉,花费,cost,MAXN 来源: https://www.cnblogs.com/zhouziyi/p/16583015.html