题面:
略
简易题解:
假设第
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 小的在前面时,总的答案就会更优
然后就是喜闻乐见的高精度了
Code
#include<bits/stdc++.h>
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<<i<<"---"<<tt<<endl;
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;
}