记录编号 |
376307 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[NOI 2007]货币兑换 |
最终得分 |
100 |
用户昵称 |
confoo |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.665 s |
提交时间 |
2017-02-26 23:32:33 |
内存使用 |
88.03 MiB |
显示代码纯文本
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using std::max;
const int N = 1e6 + 10;
const double EPS = 1e-7;
int n, sk[N];
double f[N], s, a[N], b[N], rate[N];
struct P{int i;double x, y, d;
bool operator<(const P& b)const {return d > b.d;}
inline void init() {
x = f[i]/(b[i] + rate[i]*a[i]);
y = f[i]*rate[i]/(b[i] + rate[i]*a[i]);
}
}p[N], q[N];
double slope(int i, int j) {
if (fabs(p[i].x - p[j].x) < EPS) return 1e20;
return (p[i].y - p[j].y)/(p[i].x - p[j].x);
}
void solve(int l, int r) {
if (l == r) {
//assert l == p[l].i
f[l] = max(f[l], f[l - 1]);
p[l].init();
return;
}
int mid = (l + r) >> 1;
for (int k = l, i = 0, j = mid - l + 1; k <= r; k++) q[(p[k].i <= mid ? i : j)++] = p[k];
memcpy(p + l, q, (r - l + 1)*sizeof(P));
solve(l, mid);
int top = 0;
for (int i = l; i <= mid; i++) {
while (top > 1 && slope(sk[top], sk[top - 1]) < slope(sk[top], i)) top--;
sk[++top] = i;
}
for (int x = 1, y = mid + 1; y <= r; y++) {
while (x < top && slope(sk[x], sk[x + 1]) + EPS > p[y].d) x++;
int i = p[y].i, j = sk[x];
f[i] = max(f[i], p[j].x*b[i] + p[j].y*a[i]);
}
solve(mid + 1, r);
int tot = 0;
for (int i = l, j = mid + 1; i <= mid || j <= r; tot++) {
if (i > mid || (j <= r && p[j].x < p[i].x)) q[tot] = p[j++];
else q[tot] = p[i++];
}
memcpy(p + l, q, tot*sizeof(P));
}
int main() {
freopen("cash.in", "r", stdin);
freopen("cash.out", "w", stdout);
scanf("%d%lf", &n, f);
for (int i = 1; i <= n; i++) scanf("%lf%lf%lf", a + i, b + i, rate + i), p[i].d = -b[i]/a[i], p[i].i = i;
std::sort(p + 1, p + 1 + n);
solve(1, n);
printf("%.3lf\n", f[n]);
}