>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;
}