略
假设第 i i i位大臣左手为 L i L_{i} Li, 右手的数为R_{i}
并且我们有两位大臣 i i i, j j j,考虑他们的相对位置
( P P P 是 i i i , j j j 之前的左手数值累乘)
某一个时候, 假设 i i i 在 j j j 前一个位置,则此时:
j j j 号大臣能获得的金币为 P × L i R j \frac{P \times L_{i} } {R_{j}} RjP×Li
i i i 号大臣能获得的金币为 P R i \frac{P}{R_{i}} RiP
所以这两个的最大值为 m a x ( P × L i R j , P R i ) max( \frac{P \times L_{i}} {R_{j}}, \frac{P}{R_{i}} ) max(RjP×Li,RiP)
i i i 与 j j j交换位置,则此时:
i i i号大臣能获得的金币为 P × L j R i \frac{P \times L_{j}} {R_{i}} RiP×Lj
j j j号大臣能获得的金币为 P R j \frac{P}{R_{j}} RjP
所以这两个的最大值为 m a x ( P × L j R i , P R j ) max( \frac{P \times L_{j}} {R_{i}}, \frac{P}{R_{j}} ) max(RiP×Lj,RjP)
我们来比较一下这两个的最大值:
倘若第一种情况更优,则:
m a x ( P × L j R i , P R j ) > m a x ( P × L i R j , P R i ) max( \frac{P \times L_{j}} {R_{i}}, \frac{P}{R_{j}} ) > max( \frac{P \times L_{i}} {R_{j}}, \frac{P}{R_{i}} ) max(RiP×Lj,RjP)>max(RjP×Li,RiP)
同时约去 P P P,得:
m a x ( L j R i , 1 R j ) > m a x ( L i R j , 1 R i ) max( \frac{L_{j}} {R_{i}}, \frac{1}{R_{j}} ) > max( \frac{ L_{i}} {R_{j}}, \frac{1}{R_{i}} ) max(RiLj,Rj1)>max(RjLi,Ri1)
由于
1 R j < L i R j \frac{1}{R_{j}} < \frac{ L_{i}} {R_{j}} Rj1<RjLi
且
1 R i < L j R i \frac{1}{R_{i}} < \frac{ L_{j}} {R_{i}} Ri1<RiLj
则我们只需要满足
L i R j < L j R i \frac{L{i}}{R_{j}} < \frac{ L_{j}} {R_{i}} RjLi<RiLj
即
L i × R i < L j × R j L_{i} \times R_{i} < L_{j} \times R_{j} Li×Ri<Lj×Rj
也就是说,当 L × R L \times R L×R 小的在前面时,总的答案就会更优
然后就是喜闻乐见的高精度了
#include
using namespace std;
#define _(d) while(d(isdigit(ch=getchar())))
template<class T>void g(T&t){T x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;t=f*x;}
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define repd(i,a,b) for(int i=a;i>=b;i--)
#define For(i,a,b) for(int i=a;i<b;i++)
const int N=1e4+4;
struct Man{
int l,r;
bool operator<(const Man &rhs)const{
return l*r<rhs.l*rhs.r;
}
}m[N];
int a,b,n;
struct Int{
int a[10004];//a[0] 表示位数
Int operator*(int b)const{
Int tmp; tmp.a[0]=0;
int t=log(b)/log(10);
rep(i,1,t+a[0]+2) tmp.a[i]=0;
rep(i,1,a[0]){
int tt=a[i]*b;
// cout<
int t0=0;
while(tt){
tmp.a[i+t0]+=tt%10;
tt/=10; t0++;
}
}
repd(i,t+a[0]+1,0) if(tmp.a[i]>0){
tmp.a[0]=i; break;
}
return tmp;
}
Int operator/(int b)const{
Int tmp; tmp.a[0]=0;
rep(i,1,a[0]) tmp.a[i]=0;
if(a[0]==0) return *this;
int tt=0,p=0;bool fl=0;
repd(i,a[0],1){
tt=tt*10+a[i];
if(tt>=b){
if(!fl) tmp.a[0]=i;
fl=1;
tmp.a[i]=tt/b;
p=tt%b;
tt=p;
}
}
return tmp;
}
bool operator<(Int b)const{
if(a[0]<b.a[0]) return true;
else if(a[0]>b.a[0]) return false;
else repd(i,a[0],1){
if(a[i]<b.a[i]) return true;
else if(a[i]>b.a[i]) return false;
}
}
}ans,s;
int main(){
g(n);
g(m[0].l),g(m[0].r);
rep(i,1,n) g(m[i].l), g(m[i].r);
sort(m+1,m+1+n);
ans.a[1]=1;ans.a[0]=1; s.a[1]=s.a[0]=1;
rep(i,1,n){
if(ans<s/m[i].r) ans=s/m[i].r,ans.a[0]--;
s=s*m[i].l;
}
repd(i,ans.a[0],1) printf("%d",ans.a[i]);
return 0;
}