思路:贪心。由题意可知,交换相邻两个人对于其他人并无影响。设这两个人按顺序分别为{a1,b1},{a2,b2},交换前是max{sum*1/b1,sum*a1/b2},交换后是max{sum*1/b2,sum*a2/b1},而分母为1的项一定不会被最大值考虑到,则需要考虑max{sum*a2/b1,sum*a1/b2},即max{a2/b1,a1/b2}。如果不交换更优,则有a1/b2<a2/b1,即a1×b1<a2×b2。所以,以ai∗bi为关键字进行从小到大排序,会得到最优解。最后只需扫描一遍序列就行了。由于乘积可能很大,所以需要使用高精度计算。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1005;
struct node
{
int a,b;
node(int a=0,int b=0):a(a),b(b){}
bool operator < (const node &x) const
{
return a*b<x.a*x.b;
}
};
struct bignum
{
int len,a[5000];
bignum()
{
len=1;
memset(a,0,sizeof(a));
}
bignum operator * (int num)
{
len++;
int jinwei=0;
for (int i=1;i<=len;++i)
{
a[i]=a[i]*num+jinwei;
jinwei=a[i]/100000;
a[i]%=100000;
}
if (a[len]==0)
len--;
return *this;
}
bool operator < (const bignum &b) const
{
if (b.len!=len)
return len<b.len ? 1:0;
for (int i=len;i>=1;--i)
if (a[i]!=b.a[i])
return a[i]<b.a[i] ? 1:0;
return 0;
}
bignum operator / (int num)
{
bignum c=*this;
int jiewei=0;
for (int i=len;i>=1;--i)
{
jiewei=a[i]+100000*jiewei;
c.a[i]=jiewei/num;
jiewei%=num;
}
while (c.a[c.len]==0)
c.len--;
return c;
}
bignum operator *= (int num)
{
*this=*this*num;
return *this;
}
};
void print(bignum x)
{
printf("%d",x.a[x.len]);
for (int i=x.len-1;i>=1;--i)
printf("%05d",x.a[i]);
}
int n;
node man[maxn];
int main()
{
scanf("%d",&n);
scanf("%d%d",&man[1].a,&man[1].b);
for (int i=2;i<=n+1;++i)
{
int a,b;
scanf("%d%d",&a,&b);
man[i]=node(a,b);
}
sort(man+2,man+n+2);
bignum ans,sum;
sum.a[1]=man[1].a;
for (int i=2;i<=n+1;++i)
{
ans=max(sum/man[i].b,ans);
sum*=man[i].a;
}
print(ans);
return 0;
}