1.題面:傳送門
2. 思路:
相鄰的兩個大臣的先后順序只會互相影響,并不會影響其他人的金幣數。
假設前 i-1 個人左手上的數乘積為 s 。
① 若 A 大臣排在B 大臣的前面,則:
s | |
此時的金幣數最大值為?。
② 若B大臣排在A大臣的前面,則:
s | |
此時的金幣數最大值為?。
因為每個大臣兩個手上的整數a,b>=1,所以有?。
① 若要讓,即
,則還需要滿足:
,化簡得到:
;
② 若要讓,即
,則還需要滿足:
,化簡得到:
。
可以看出,若要取得金幣數的最小值,則需要排在前面的大臣左右手兩個數的乘積要小于等于排在后面的大臣左右手兩個數的乘積。
最后需要注意下累成會涉及到高精度的運算,這里參考之前學習大數相乘和大數相除。(注意vector是從低精度開始存儲的,在比較和輸出時注意順序!)
#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ll long long
#define int long long
#define pii pair<int, int>
#define lowbit(x) (x &(-x))
#define ls(x) x<<1
#define rs(x) (x<<1+1)
#define me(ar) memset(ar, 0, sizeof ar)
#define mem(ar,num) memset(ar, num, sizeof ar)
#define rp(i, n) for(int i = 0, i < n; i ++)
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define pre(i, n, a) for(int i = n; i >= a; i --)
#define IOS ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
const int way[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
using namespace std;
const int inf = 0x7fffffff;
const double PI = acos(-1.0);
const double eps = 1e-6;
const ll mod = 1e9 + 7;
const int N = 2e5 + 5;int n, y;
string x;
vector<int> X, A, ans;struct node{int id;int l;int r;int Pr;
}a[N];bool cmp(node x, node y){return x.l*x.r < y.l*y.r;
}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;//去除前導0while(!C.back() && C.size()>1) C.pop_back();return C;
}vector<int> div(vector<int> &A, int b, int &r)
{vector<int> C;r = 0;for(int i = A.size() - 1; i >= 0; i -- ){r = r * 10 + A[i];C.push_back(r / b);r %= b;}reverse(C.begin(), C.end());while(C.size() > 1 && C.back() == 0 ) C.pop_back();//去前導0return C;
}vector<int> Comparison(vector<int> &A, vector<int> &B){if(A.size() > B.size()) return A;if(A.size() < B.size()) return B;for(int i = ans.size()-1; i >= 0; i --){ // 注意:vector存儲的高精度都是低位在前,高位在后if(A[i] > B[i]) return A;if(A[i] < B[i]) return B;}return A;
}signed main()
{IOS;cin >> n >> x >> y;for(int i = x.size() - 1; ~i; i --){X.push_back(x[i] - '0');}for(int i = 1; i <= n; i ++){a[i].id = i;cin >> a[i].l >> a[i].r;}sort(a+1, a+n+1, cmp);int r = 0;for(int i = 1; i <= n; i ++){
// cout << a[i].id << " " << a[i].l << " " << a[i].r << endl; // debugA = div(X, a[i].r, r); // 計算前i-1個l乘積除以當前r的金幣數
// for(int j = 0; j < A.size(); j ++){ // debug
// cout << A[j];
// }cout << endl;ans = Comparison(A, ans); // 比較vector(金幣數)大小X = mul(X, a[i].l); // 然后再乘以當前的r得到前i個l的乘積
// for(int j = 0; j < X.size(); j ++){ // debug
// cout << X[j];
// }cout << endl;}for(int i = ans.size()-1; i >= 0 ; i --){ // 注意:從高位開始輸出cout << ans[i];}cout << endl;return 0;
}