题意
传送门 NC 16561
题解
考虑相邻的两个大臣,其交换顺序不会对其前面或后面的大臣获得的金币造成影响;假设大臣 i i i 排在大臣 j j j 前面时,这两个大臣获得的金币最大值最小,设排在前面的人左手数字乘积为 x x x,则有
m a x { x b i , x a i b j } ≤ m a x { x b j , x a j b i } max\{\frac{x}{b_{i}},\frac{xa_{i}}{b_{j}}\}\leq max\{\frac{x}{b_{j}},\frac{xa_{j}}{b_{i}}\} max{bix,bjxai}≤max{bjx,bixaj}
考虑到
x b i ≤ x a j b i , x b j ≤ x a i b j \frac{x}{b_{i}}\leq \frac{xa_{j}}{b_{i}}\ ,\ \frac{x}{b_{j}}\leq \frac{xa_{i}}{b_{j}} bix≤bixaj , bjx≤bjxai
若 x b i ≥ x a i b j \frac{x}{b_{i}}\geq \frac{xa_{i}}{b_{j}} bix≥bjxai,满足条件;若 x b i < x a i b j \frac{x}{b_{i}}< \frac{xa_{i}}{b_{j}} bix<bjxai,则应满足
x a i b j ≤ x a j b i \frac{xa_{i}}{b_{j}}\leq\frac{xa_{j}}{b_{i}} bjxai≤bixaj
化简
a i b i ≤ a j b j a_{i}b_{i}\leq a_{j}b_{j} aibi≤ajbj
以此对大臣排序,大数求金币最大值即可。测试点中存在脏数据,不能读入多组数据。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
class bigInt
{
#define maxa 1005
#define base 10000
public:
int limit;
int arr[maxa];
bigInt(int n)
{
memset(arr, 0, sizeof(arr));
limit = 0;
arr[limit] = n;
}
bigInt(const bigInt &a)
{
memset(arr, 0, sizeof(arr));
limit = a.limit;
for (int i = 0; i <= limit; i++)
arr[i] = a.arr[i];
}
void operator*=(const int n)
{
int c = 0;
for (int i = 0; i <= limit; i++)
{
arr[i] = arr[i] * n + c;
if (arr[i] >= base)
{
c = arr[i] / base;
arr[i] %= base;
if (i == limit)
{
++limit;
}
}
else
{
c = 0;
}
}
}
bigInt operator/(const int n)
{
bigInt a = bigInt(*this);
for (int i = a.limit; i >= 0; i--)
{
if (a.arr[i] < n && i == a.limit && i > 0)
--a.limit;
if (i > 0)
a.arr[i - 1] += a.arr[i] % n * base;
a.arr[i] /= n;
}
return a;
}
friend bigInt mx(const bigInt &a, const bigInt &b)
{
if (a.limit != b.limit)
{
return a.limit > b.limit ? a : b;
}
for (int i = a.limit; i >= 0; i--)
{
if (a.arr[i] == b.arr[i])
continue;
return a.arr[i] > b.arr[i] ? a : b;
}
return a;
}
friend void output(const bigInt &a)
{
printf("%d", a.arr[a.limit]);
for (int i = a.limit - 1; i >= 0; i--)
{
printf("%04d", a.arr[i]);
}
putchar('\n');
}
};
#define maxn 1005
int a[maxn], b[maxn], r[maxn];
bool cmp(int i, int j)
{
return a[i] * b[i] < a[j] * b[j];
}
int main()
{
int n;
scanf("%d", &n);
int A, B;
scanf("%d%d", &A, &B);
for (int i = 0; i < n; i++)
{
r[i] = i;
scanf("%d%d", a + i, b + i);
}
sort(r, r + n, cmp);
bigInt f = bigInt(A), res = bigInt(0);
for (int i = 0; i < n; i++)
{
res = mx(res, f / b[r[i]]);
f *= a[r[i]];
}
output(res);
return 0;
}