这道题是一道邻接交换模型贪心加上高精度。
我们考虑位置 i i i 和位置 i + 1 i+1 i+1
设 t = ∏ j = 1 i − 1 a j t=\prod\limits_{j=1}^{i-1}a_j t=j=1∏i−1aj
- 如果不交换:
那么位置 i i i 和位置 i + 1 i+1 i+1 的可获得金币分别为:
t b i , t ⋅ a i b i + 1 \frac{t}{b_i},\frac{t\cdot a_i}{b_{i+1}} bit,bi+1t⋅ai
同时除以 t t t 再同时乘 b i b i + 1 b_ib_{i+1} bibi+1 变为:
b i + 1 , a i b i b_{i+1},a_ib_i bi+1,aibi - 如果交换:
那么位置 i i i 和位置 i + 1 i+1 i+1 的可获得金币分别为:
t b i + 1 , t ⋅ a i + 1 b i \frac{t}{b_{i+1}},\frac{t\cdot a_{i+1}}{b_i} bi+1t,bit⋅ai+1
同时除以 t t t 再同时乘 b i b i + 1 b_ib_{i+1} bibi+1 变为:
b i , a i + 1 b i + 1 b_i,a_{i+1}b_{i+1} bi,ai+1bi+1
然后我们就要比较 max ( b i + 1 , a i b i ) \max(b_{i+1},a_ib_i) max(bi+1,aibi) 和 max ( b i , a i + 1 b i + 1 ) \max(b_i,a_{i+1}b_{i+1}) max(bi,ai+1bi+1) 那个小哪个大,如果交换小,就交换,反之不交换。
我们可以把式子写成 max ( b i + 1 , a i b i ) < max ( b i , a i + 1 b i + 1 ) \max(b_{i+1},a_ib_i)<\max(b_i,a_{i+1}b_{i+1}) max(bi+1,aibi)<max(bi,ai+1bi+1),当然我们可以再化简写成 a i b i < a i + 1 b i + 1 a_ib_i<a_{i+1}b_{i+1} aibi<ai+1bi+1 为什么,我们可以想一下极端数据如果 b i + 1 > a i b i b_{i+1}>a_ib_i bi+1>aibi 那么 b i + 1 b_{i+1} bi+1 肯定小于 a i + 1 b i + 1 a_{i+1}b_{i+1} ai+1bi+1 反之同理,所以可以化简。
代码:
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 1010;
typedef pair<int, int> pii;
int n; pii a[N];
namespace bignum {
vector<int> convert(int x) {
vector<int> t;
do t.push_back(x % 10), x /= 10; while (x);
return t;
}
void print(vector<int> t) {
for (int i = t.size() - 1; i >= 0; --i)
putchar(t[i] ^ 48);
putchar('\n');
}
vector<int> mul(vector<int> a, int b) {
vector<int> c; int t = 0;
for (int i = 0; i < a.size() || t; ++i) {
if (i < a.size()) t += a[i] * b;
c.push_back(t % 10);
t /= 10;
}
while (c.size() > 1 && c.back() == 0) c.pop_back();
return c;
}
vector<int> div(vector<int> a, int b) {
int r = 0; vector<int> c;
for (int i = a.size() - 1; i >= 0; --i) {
r = r * 10 + a[i];
c.push_back(r / b);
r %= b;
}
reverse(c.begin(), c.end());
while (c.size() > 1 && c.back() == 0) c.pop_back();
return c;
}
vector<int> maximum(vector<int> a, vector<int> b) {
if (a.size() > b.size()) return a;
else if (a.size() < b.size()) return b;
else {
for (int i = a.size() - 1; i >= 0; --i) {
if (a[i] > b[i]) return a;
else if (a[i] < b[i]) return b;
}
}
return a;
}
}
bool cmp(pii a, pii b) {
return a.x * a.y < b.x * b.y;
}
int main() {
scanf("%d", &n);
for (int i = 0; i <= n; ++i) {
scanf("%d%d", &a[i].x, &a[i].y);
}
sort(a + 1, a + n + 1, cmp);
// int res = 0, sum = a[0].x;
vector<int> sum = bignum::convert(a[0].x), res;
for (int i = 1; i <= n; ++i) {
vector<int> t = bignum::div(sum, a[i].y);
res = bignum::maximum(t, res);
sum = bignum::mul(sum, a[i].x);
// int t = sum / a[i].y;
// res = max(res, t);
// sum *= a[i].x;
}
bignum::print(res);
// cout << res << endl;
return 0;
}