2 条题解
-
4
首先微扰法证明贪心策略,目前假如到了第个人这里,后面的人编号是,设左手是,右手是,然后我们前面部分的结果都是,我们目前计算第这个人的得分,假如不交换顺序,其实就是前面的乘积在乘以然后除以,设前部分乘积是,也就是
,交换了就是
如果交换前的结果小就是
<
通分以后约掉你发现就是
所以按照小的优先,排序即可。
然后就是高精度乘法和除法的结合,这里预处理了前缀积的结果到字符串
#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e3 + 5; int n; struct node { int l, r; bool operator < (const node &x) const { return l * r < x.l * x.r; } } a[N]; vector<int> s[N]; vector<int> mul(vector<int> &a, int b) { vector<int> c; int t = 0; for (int i = 0; i < a.size(); i++) { t += a[i] * b; c.push_back(t % 10); t /= 10; } while (t) { c.push_back(t % 10); t /= 10; } return c; } vector<int> div(vector<int> &a, int b) { vector<int> c; int x = 0; for (int i = a.size() - 1; i >= 0; i--) { x = x * 10 + a[i]; c.push_back(x / b); x %= b; } reverse(c.begin(), c.end()); while (c.size() > 1 && !c.back()) c.pop_back(); // reverse(c.begin(), c.end()); return c; } void print(vector<int> &c) { for (int i = c.size() - 1; i >= 0; i--) cout << c[i]; cout << "\n"; } vector<int> cmp(vector<int> &a, vector<int> &b) { if (a.size() > b.size()) return a; if (b.size() > a.size()) return b; for (int i = a.size() - 1; i >= 0; i--) { if (a[i] > b[i]) return a; if (a[i] < b[i]) return b; } return a; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n; for (int i = 0; i <= n; i++) cin >> a[i].l >> a[i].r; sort(a + 1, a + n + 1); for (int i = 0; i < n; i++) { if (i == 0) s[i].push_back(a[0].l); else { s[i] = mul(s[i - 1], a[i].l); } } vector<int> ans(1, 0); for (int i = 1; i <= n; i++) { vector<int> b = div(s[i - 1], a[i].r); ans = cmp(ans, b); } print(ans); return 0; }
- 1
信息
- ID
- 1490
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 3
- 标签
- 递交数
- 32
- 已通过
- 21
- 上传者