有N种汽油每种有三个属性:密度
ai
,强度
ci
,价格
bi
。用第i种汽油
m
kg拥有
一看数据范围。。单纯形boom。。
好了我们重新考虑一下吧。。
如果我们令
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 75000;
struct Point {
double x, y;
Point(double _x = 0, double _y = 0) : x(_x), y(_y) { }
Point operator/ (double b) const { return Point(x / b, y / b); }
};
int q[N], a[N], b[N], c[N], o[N];
Point intersection(int u, int v) {
double det = a[u] * b[v] - a[v] * b[u];
return Point(b[v] * c[u] - b[u] * c[v], a[u] * c[v] - a[v] * c[u]) / det;
}
bool is_convex(int u, int v, int w) {
Point p = intersection(v, w);
return a[u] * p.x + b[u] * p.y > c[u];
}
int main() {
int i, x, y, A, B, n;
scanf("%d%d%d", &n, &A, &B);
for (i = 0; i < n; ++i) {
scanf("%d%d%d", a + i, b + i, c + i);
o[i] = i;
}
sort(o, o + n, [](int i,int j){return a[i] * b[j] - a[j] * b[i] > 0;});
int f = 0, r = 0;
for (i = 0; i < n; ++i) {
x = o[i];
if (f < r) {
y = q[r - 1];
if (a[x] * b[y] == a[y] * b[x]) {
if (c[y] / b[y] >= c[x] / b[x]) continue;
--r;
}
}
while (r - f >= 2 && !is_convex(q[r - 2], q[r - 1], x)) --r;
q[r++] = x;
}
for (; r - f >= 2; ++f)
if (intersection(q[f], q[f + 1]).x >= 0) break;
for (; r - f >= 2; --r)
if (intersection(q[r - 2], q[r - 1]).y >= 0) break;
double ans = min(1.0 * B * c[q[f]] / b[q[f]], 1.0 * A * c[q[r - 1]] / a[q[r - 1]]);
for (i = f + 1; i < r; ++i) {
Point p = intersection(q[i - 1], q[i]);
ans = min(ans, A * max(p.x, 0.0) + B * max(p.y, 0.0));
}
printf("%.6f\n", ans);
return 0;
}
Fuel
Time Limit: 500MS
Description
A fuel station has infinite amount of each of N kinds of fuel. Each kind of fuel has density ai, cost bi and intensity ci. m kilograms of such fuel has volume mai, intensity mci and costs mbi dollars. Your car can store any mixture of different kinds of fuel such that the overall volume does not exceed A. You have B dollars. Your task is to determine the maximal overall intensity of the fuel you can buy. Note that you can buy any nonnegative amount of any kind of fuel, not necessarily an integer number of kilograms.
Input
The first line of the input contains three integers N, A, B (1≤ N≤ 75000, 1≤ A, B≤ 1000). Each of the next N lines describes one kind of fuel. i+1-st line contains three integers ai, bi, ci (0 i, bi, ci≤ 100).
Output
The only line of the output must contain single number with at least 6 digits after the decimal point, being the maximal overall intensity.
Sample Input
2 1 1
1 2 6
2 1 6
Sample Output
4.000000
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Point {
double x, y;
Point() { }
Point(double _x, double _y) : x(_x), y(_y) { }
Point operator+ (const Point &b) const { return Point(x + b.x, y + b.y); }
Point operator- (const Point &b) const { return Point(x - b.x, y - b.y); }
double operator* (const Point &b) const { return x * b.y - y * b.x; }
Point operator* (double b) const { return Point(x * b, y * b); }
Point operator/ (double b) const { return Point(x / b, y / b); }
};
const int N = 75000;
int n, d, e, q[N], a[N], b[N], c[N], order[N];
bool cmp(int i, int j) {
return a[i] * b[j] - a[j] * b[i] > 0;
}
double dist(int u) {
return c[u] / sqrt(a[u] * a[u] + b[u] * b[u]);
}
Point intersection(int u, int v) {
double det = a[u] * b[v] - a[v] * b[u];
return Point(b[v] * c[u] - b[u] * c[v], a[u] * c[v] - a[v] * c[u]) / det;
}
bool is_convex(int u, int v, int w) {
Point p = intersection(v, w);
return a[u] * p.x + b[u] * p.y > c[u];
}
int main() {
int i, u, v;
scanf("%d%d%d", &n, &d, &e);
for (i = 0; i < n; ++i) {
scanf("%d%d%d", a + i, b + i, c + i);
order[i] = i;
}
sort(order, order + n, cmp);
int f = 0, r = 0;
for (i = 0; i < n; ++ i) {
u = order[i];
if (f < r) {
v = q[r - 1];
if (!cmp(u, v) && !cmp(v, u)) {
if (dist(v) >= dist(u)) continue;
--r;
}
}
while (r - f >= 2 && !is_convex(q[r - 2], q[r - 1], u)) --r;
q[r++] = u;
}
while (r - f >= 2) {
Point p = intersection(q[f], q[f + 1]);
if (p.x >= 0) break;
++f;
}
while (r - f >= 2) {
Point p = intersection(q[r - 2], q[r - 1]);
if (p.y >= 0) break;
--r;
}
double ans = min(1. * e * c[q[f]] / b[q[f]], 1. * d * c[q[r - 1]] / a[q[f - 1]]);
for (i = f + 1; i < r; ++i) {
Point p = intersection(q[i - 1], q[i]);
ans = min(ans, d * max(p.x, 0.0) + e * max(p.y, 0.0));
}
printf("%.6f\n", ans);
return 0;
}