NOIP2012提高组国王游戏 贪心 + 高精度
Posted CzYoL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
#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; }
以上是关于NOIP2012提高组国王游戏 贪心 + 高精度的主要内容,如果未能解决你的问题,请参考以下文章
luoguP1080 国王游戏 题解(NOIP2012)(贪心+高精)