【题目分析】
看到数据的范围,只有40%数据是可以用二进制过的。然而这也打消我们暴力枚举的念头。
思路从枚举到了贪心。
如果相邻的两个大臣进行交换,对之后的区间的答案并不影响。
就要进行神奇的数学推导%&*%&……()&
推得—>如果
#define M 1005
#include
#include
#include
#include
#define P 10000
using namespace std;
struct node{
int l,r;
}a[M];
bool cmp(node x,node y){
int m1=x.l*x.r;
int m2=y.l*y.r;
if(m1!=m2)return m1return x.r>y.r;
}
struct Bint{
int num[5005],sz;
Bint(){
memset(num,0,sizeof(num));
sz=0;
}
Bint operator*(const Bint &x){
Bint t;
for(int i=0;ifor(int j=0;j1]+=t.num[i+j]/P;
t.num[i+j]%=P;
}
}
int SZ=sz+x.sz-1;
if(t.num[SZ])SZ++;
t.sz=SZ;
return t;
}
Bint operator/(const int &x){
Bint t;
for(int i=0;iint an=0;
for(int i=sz-1;i>=0;i--)
if(i)t.num[i-1]+=(t.num[i]%x)*P;
for(int i=sz-1;i>=0;i--)
t.num[i]/=x;
while(!t.num[t.sz-1]&&t.sz>1)t.sz--;
return t;
}
bool operator>(const Bint &x)const{
if(sz>x.sz)return 1;
else if(szreturn 0;
for(int i=sz-1;i>=0;i--){
if(num[i]>x.num[i])return 1;
else if(num[i]return 0;
}return 0;
}
void Print(){
printf("%d",num[sz-1]);
for(int i=sz-2;i>=0;i--)printf("%04d",num[i]);
puts("");
}//事实证明,这个十分好用
}sum,ans;
int main(){
int i,j,n;
scanf("%d",&n);
for(i=0;i<=n;i++)scanf("%d %d",&a[i].l,&a[i].r);
sort(a+1,a+n+1,cmp);
int k=a[0].l;
int len=0;
while(k){
sum.num[len++]=k%P;
k/=P;
}sum.sz=len;
for(i=1;i<=n;i++){
Bint res=sum/a[i].r;
if(res>ans)ans=res;
Bint w;
k=a[i].l,len=0;
while(k){
w.num[len++]=k%P;
k/=P;
}w.sz=len;
sum=sum*w;
}
ans.Print();
return 0;
}