>Link
ybtoj国王游戏
>解题思路
很显然一道贪心(但是我一开始贪错了==)
我们设 a i 、 b i a_i、b_i ai、bi为第 i i i个人左右手上的数, s i s_i si为前 i i i个人所有人左手上数的乘积
考虑邻位交换,第 i i i个人与第 i + 1 i+1 i+1个人交换位置
则这两个位的最大值转换如下:
m a x ( s i − 1 b i , s i − 1 ∗ a i b i + 1 ) → m a x ( s i − 1 b i + 1 , s i − 1 ∗ a i + 1 b i ) max(\frac{s_{i-1}}{b_i},\frac{s_{i-1}*a_i}{b_{i+1}})→max(\frac{s_{i-1}}{b_{i+1}},\frac{s_{i-1}*a_{i+1}}{b_i}) max(bisi−1,bi+1si−1∗ai)→max(bi+1si−1,bisi−1∗ai+1)
我们发现相邻两个位交换并不会影响到其他的位的值,并且
如果左边的值比右边的值大的话,就进行邻位交换,使最大值更小
所以比较左右两边式子
m a x ( s i − 1 b i , s i − 1 ∗ a i b i + 1 ) , m a x ( s i − 1 b i + 1 , s i − 1 ∗ a i + 1 b i ) max(\frac{s_{i-1}}{b_i},\frac{s_{i-1}*a_i}{b_{i+1}}),max(\frac{s_{i-1}}{b_{i+1}},\frac{s_{i-1}*a_{i+1}}{b_i}) max(bisi−1,bi+1si−1∗ai),max(bi+1si−1,bisi−1∗ai+1)
[两边除以 s i − 1 s_{i-1} si−1]
m a x ( 1 b i , a i b i + 1 ) , m a x ( 1 b i + 1 , a i + 1 b i ) max(\frac{1}{b_i},\frac{a_i}{b_{i+1}}),max(\frac{1}{b_{i+1}},\frac{a_{i+1}}{b_i}) max(bi1,bi+1ai),max(bi+11,biai+1)
[两边再乘上 b i ∗ b i + 1 b_i*b_{i+1} bi∗bi+1]
m a x ( b i + 1 , a i ∗ b i ) , m a x ( b i , a i + 1 ∗ b i + 1 ) max(b_{i+1},a_i*b_i),max(b_{i},a_{i+1}*b_{i+1}) max(bi+1,ai∗bi),max(bi,ai+1∗bi+1)
因为 a i ∗ b i > b i , a i + 1 ∗ b i + 1 > b i + 1 a_i*b_i>b_i,a_{i+1}*b_{i+1}>b_{i+1} ai∗bi>bi,ai+1∗bi+1>bi+1,
所以我们只用比较 a i ∗ b i a_i*b_i ai∗bi 和 a i + 1 ∗ b i + 1 a_{i+1}*b_{i+1} ai+1∗bi+1 就行了
得出,我们按照 a i ∗ b i a_i*b_i ai∗bi从小到大把大臣们排序就行了
最后这道题需要用高精度==
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1010
#define maxn 4000
using namespace std;
struct node
{
int a, b;
} s[N];
int n, A, B, ans[maxn + 5], w[maxn + 5], p[maxn + 5];
bool cmp (node aa, node bb) {
return aa.a * aa.b < bb.a * bb.b;}
void gjcheng (int x)
{
int g = 0;
for (int i = maxn; i > 0; i--)
{
w[i] = w[i] * x + g;
g = w[i] / 10;
w[i] %= 10;
}
}
void gjchu (int x)
{
int g = 0, t = 0;
while (w[t] == 0 && t < maxn) t++;
for (int i = t; i <= maxn; i++)
{
p[i] = w[i] + g;
g = p[i] % x * 10;
p[i] /= x;
}
}
void write ()
{
int l = 0;
while (ans[l] == 0 && l < maxn) l++;
for (int i = l; i <= maxn; i++)
putchar (ans[i] + '0');
}
int main()
{
scanf ("%d%d%d", &n, &A, &B);
for (int i = 1; i <= n; i++) scanf ("%d%d", &s[i].a, &s[i].b);
sort (s + 1, s + 1 + n, cmp);
int g = 0;
w[maxn] = A;
for (int i = maxn; i > 0; i--)
{
w[i] += g;
g = w[i] / 10;
w[i] %= 10;
}
for (int i = 1; i <= n; i++)
{
memset (p, 0, sizeof (p));
gjchu (s[i].b);
for (int j = 0; j <= maxn; j++)
{
if (ans[j] > p[j]) break;
if (ans[j] < p[j])
{
for (int k = 0; k <= maxn; k++) ans[k] = p[k];
break;
}
}
gjcheng (s[i].a);
}
write();
return 0;
}