国王游戏

首先,每个人在左、右手上面分别有一个整数。然后,国王游戏与皇后游戏_#include位大臣排成一排,国王站在队伍的最前面。每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
现在要使金币的最大值最小


可以来试着推一下
先把关系设好
假设加上国王只有下面三个人(大臣国王游戏与皇后游戏_NOIP_02国王游戏与皇后游戏_贪心_03表示,金币用国王游戏与皇后游戏_NOIP_04


左手

右手

国王游戏与皇后游戏_排序_05

国王游戏与皇后游戏_NOIP_06

国王游戏与皇后游戏_排序_07

国王游戏与皇后游戏_NOIP_08

国王游戏与皇后游戏_算法_09

国王游戏与皇后游戏_排序_10

国王游戏与皇后游戏_#include_11

国王游戏与皇后游戏_算法_12

国王游戏与皇后游戏_#include_13

这个国王游戏与皇后游戏_#include_14编辑器不支持多行等式的样子,只好用图片

当前答案:

国王游戏与皇后游戏_#include_15


两位大臣交换后:

国王游戏与皇后游戏_算法_16


假设不交换更优

那么国王游戏与皇后游戏_#include_17

设这四项分别为国王游戏与皇后游戏_贪心_18

显然国王游戏与皇后游戏_贪心_19

又有国王游戏与皇后游戏_NOIP_20

这个国王游戏与皇后游戏_算法_21是随便插空都可以的

但可知国王游戏与皇后游戏_算法_22一定大于国王游戏与皇后游戏_算法_23

国王游戏与皇后游戏_NOIP_24

所以国王游戏与皇后游戏_算法_25

得出不等式国王游戏与皇后游戏_算法_26

结论国王游戏与皇后游戏_算法_27国王游戏与皇后游戏_算法_28从小到大排序会使答案更优

国王游戏就是这样

比较简单

But要高精

​传送门​​ 代码:

#include <iostream>
#include <complex>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
namespace BigInteger {
struct Big_integer {
int d[10005], len;
void clean() {while(len > 1 and !d[len - 1]) len--;}
Big_integer() {memset(d, 0, sizeof d); len = 1;}
Big_integer(int num) {*this = num;}
Big_integer operator = (const char* num) {
memset(d, 0, sizeof d);
len = strlen(num);
for (int i = 0; i < len; i++) d[i] = num[len - 1 - i] - '0';
clean();
return *this;
}
Big_integer operator = (int num) {
char s[10005];
sprintf(s, "%d", num);
*this = s;
return *this;
}
Big_integer operator * (const Big_integer &b) const {
int i, j;
Big_integer c;
c.len = len + b.len;
for (j = 0; j < b.len; j++)
for (i = 0; i < len; i++)
c.d[i + j] += d[i] * b.d[j];
for (i = 0; i < c.len - 1; i++) {
c.d[i + 1] += c.d[i] / 10;
c.d[i] %= 10;
}
c.clean();
return c;
}
Big_integer operator / (const int &b) {
int i, j, a = 0;
Big_integer c = *this;
for (i = len - 1; i >= 0; i--) {
a = a * 10 + d[i];
for (j = 0; j < 10; j++)
if (a < b * (j + 1)) break;
c.d[i] = j;
a = a - b * j;
}
c.clean();
return c;
}
bool operator < (const Big_integer &b) const {
if (len != b.len) return len < b.len;
for (int i = len - 1; i >= 0; i--)
if (d[i] != b.d[i])
return d[i] < b.d[i];
return false;
}
string str() const {
char s[10005];
for (int i = 0; i < len; i++) s[len - 1 - i] = d[i] + '0';
return s;
}
};
istream& operator >> (istream& in, Big_integer &x) {
string s;
in >> s;
x = s.c_str();
return in;
}
ostream& operator << (ostream& out, const Big_integer &x) {
out << x.str();
return out;
}
}
using namespace BigInteger;
struct node {
int a, b;
friend bool operator < (const node x, const node y) {
return x.a * x.b < y.a * y.b;
}
}e[10010];
int n;
Big_integer ans, tmp = 1;

int main(int argc, char const *argv[]) {
scanf("%d%d%d", &n, &e[1].a, &e[1].b);
for (int i = 2; i <= n + 1; i++) scanf("%d%d", &e[i].a, &e[i].b);
sort(e + 2, e + n + 2);
for (int i = 2; i <= n + 1; i++) {
tmp = tmp * e[i - 1].a;
ans = max(ans, tmp / e[i].b);
}
cout << ans << endl;
}

再看少麻烦点的皇后游戏




皇后游戏

皇后有国王游戏与皇后游戏_#include位大臣,每位大臣的左右手上面分别写上了一个正整数。要为国王游戏与皇后游戏_#include位大臣颁发奖金,其中第国王游戏与皇后游戏_贪心_31位大臣所获得的奖金数目

为第国王游戏与皇后游戏_NOIP_32位大臣所获得奖金数目与前国王游戏与皇后游戏_贪心_31位大臣左手上的数的和的较大值再加上第国王游戏与皇后游戏_贪心_31位大臣右手上的数

即:设第国王游戏与皇后游戏_贪心_31位大臣左手上的正整数为国王游戏与皇后游戏_贪心_36,右手上的正整数为国王游戏与皇后游戏_NOIP_37,则第国王游戏与皇后游戏_贪心_31位大臣获得的奖金数目为国王游戏与皇后游戏_#include_39可以表达为:

国王游戏与皇后游戏_NOIP_40


可以仿照着国王游戏自己yy一下

来看怎么做

我们还是假设两个大臣编号为国王游戏与皇后游戏_贪心_31国王游戏与皇后游戏_算法_42

国王游戏与皇后游戏_排序_43

则当前答案为:

国王游戏与皇后游戏_算法_44


交换两位大臣的位置后:

国王游戏与皇后游戏_排序_45


假设交换更优

那么第二个等式大于第一个等式

发现两边都有国王游戏与皇后游戏_NOIP_46,消去:

国王游戏与皇后游戏_NOIP_47

再把共同的国王游戏与皇后游戏_算法_48提出来:

国王游戏与皇后游戏_NOIP_49

把两边分别共有的拿出来:

国王游戏与皇后游戏_NOIP_50

移项:

国王游戏与皇后游戏_贪心_51

可知两个中大的会被减掉然后剩下小的那个的相反数

国王游戏与皇后游戏_排序_52

最后得到:国王游戏与皇后游戏_#include_53

又是一个简单式子

国王游戏与皇后游戏_NOIP_54