【NOIP2012提高组】国王游戏 贪心 + 高精度
题目分析
题目答案不具有单调性,所以不可以二分,转而思考贪心。因为无法确定位置,所以考虑如何才能让对于每一个$1 ~ i$使得$i$的答案最大,即$1 ~ i$最后一个最优。若设对于位置$i$,$a[i]$表示左手,$b[i]$表示右手,$S$为其前面所有人的左手之积,那么他的答案就是$\frac{S}{b[i]}$,如果存在在$i$后边的$j$的答案更优, 即$\frac{S * a[i]}{b[j]} > \frac{S * a[j]}{b[i]} => a[i] * b[i] > a[j] * b[j]$,这样只要我们以a[i] * b[i]为关键字从小到大排序,就能保证每个前缀的最后一个都是最优的,只要$o(n)$扫一遍取最大值即可,记得使用高精度。
code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N = 1050; int n, a[N], b[N], c[N], ka, kb, kc; inline int read(){ int i = 0, f = 1; char ch = getchar (); for (; (ch < '0' || ch > '9' ) && ch != '-' ; ch = getchar ()); if (ch == '-' ) f = -1, ch = getchar (); for (; ch >= '0' && ch <= '9' ; ch = getchar ()) i = (i << 3) + (i << 1) + (ch - '0' ); return i * f; } inline void wr( int x){ if (x < 0) putchar ( '-' ), x = -x; if (x > 9) wr(x / 10); putchar (x % 10 + '0' ); } struct bign{ int len, s[10000]; bign():len(0){ memset (s, 0, sizeof s);} bign( int x):len(0){ memset (s, 0, sizeof s); while (x){ s[++len] = x % 10; x /= 10; } if (!len) len = 1; } inline void clear(){ while (len > 1 && s[len] == 0) len--; } inline bign operator * ( const bign &b) const { bign ret; ret.len = len + b.len + 5; for ( int i = 1; i <= len; i++) for ( int j = 1; j <= b.len; j++) ret.s[i + j - 1] += s[i] * b.s[j]; for ( int i = 1; i <= ret.len; i++) if (ret.s[i] >= 10){ ret.s[i + 1] += ret.s[i] / 10; ret.s[i] %= 10; } ret.clear(); return ret; } inline bign operator - ( const bign &b) const { bign ret; ret.len = len; for ( int i = 1; i <= len; i++){ ret.s[i] = ret.s[i] + s[i]; if (i <= b.len) ret.s[i] = ret.s[i] - b.s[i]; if (ret.s[i] < 0){ ret.s[i + 1]--; ret.s[i] += 10; } } ret.clear(); return ret; } bign operator / ( int b) { bign c; int f = 0; for ( int i = len; i >= 1; i--){ f = f * 10 + s[i]; while (!(f < b)){ f -= b; c.s[i]++; } } c.len = len; c.clear(); return c; } inline bool operator > ( const bign &b) const { if (len != b.len) return len > b.len; for ( int i = len; i >= 1; i--) if (s[i] != b.s[i]) return s[i] > b.s[i]; return false ; } inline bool operator == ( const bign &b) const { if (len != b.len) return false ; for ( int i = len; i >= 1; i--) if (s[i] != b.s[i]) return false ; return true ; } inline bool operator < ( const bign &b) const { if (len != b.len) return len < b.len; for ( int i = len; i >= 1; i--) if (s[i] != b.s[i]) return s[i] < b.s[i]; return false ; } inline void print(){ for ( int i = len; i >= 1; i--) wr(s[i]); } }fa, ans, big0, big10; struct node{ int a, b, c; inline bool operator < ( const node &u) const { if (c != u.c) return c < u.c; return b > u.b; } }data[N]; int main(){ n = read(), ka = read(), kb = read(); for ( int i = 1; i<= n; i++){ data[i].a = read(), data[i].b = read(); data[i].c = data[i].a * data[i].b; } sort(data + 1, data + n + 1); fa = ka; ans = 0; bign tmpa, t; for ( int i = 1; i <= n; i++){ tmpa = data[i].a; t = fa / data[i].b; if (t > ans) ans = t; fa = fa * tmpa; } ans.print(); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步