贪心,按照a*b升序排序,如果相同,则a小的在前。
解释一下:
排序的时候,我们假设前面的已经排好了,而且当前这两个为a1,b1,a2,b2
那么 这两个怎样排对后面的影响都是一样的,所以只需看这两个大臣的顺序对这两个的影响,
我们肯定是
returnk∗a1/b2<k∗a2/b1
k表示前面的左手乘积,化简一下就是
returna1∗b1<a2∗b2
如果直接上单纯的计算会炸掉,60分。
需要加高精。
我压了4位。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<queue>
#define LL long long
const long long P=10000;
using namespace std;
int n;
struct H{
LL a,b,c;
}p[1009];
LL ak,bk,ans;
bool cmp(H x,H y)
{
if(x.c==y.c) return x.b<y.b;
return x.c<y.c;
}
int s1[1009],s2[1009],s3[1009],len,len2,len3;
void MAX()//比较大小
{
int f=0;
if(len2<len3) return;
if(len2==len3)
{
for(int i=len2;i>=1;i--)
{
if(s2[i]<s3[i])return;
if(s2[i]>s3[i]){f=1;break;}
}
}
if(len2>len3) f=1;
if(f)
{
for(int i=1;i<=len2;i++) s3[i]=s2[i];
len3=len2;
}
}
int main()
{
freopen("game.in","r",stdin);
scanf("%d%lld%lld",&n,&ak,&bk);
for(int i=1;i<=n;i++) scanf("%lld%lld",&p[i].a,&p[i].b),p[i].c=p[i].a*p[i].b;
sort(p+1,p+n+1,cmp);
p[0].a=ak;
len=1;
s1[1]=1;
for(int i=0;i<=n-1;i++)//高精乘p[0~n-1].a;
{
LL k=p[i].a;//cout<<k<<endl;
for(int j=1;j<=len;j++)
{
s1[j]=s1[j]*k;
}
for(int j=1;j<=len;j++)
{
s1[j+1]+=s1[j]/P;
s1[j]%=P;
}
if(s1[len+1]) len++;
k=p[i+1].b;
for(int j=1;j<=len;j++) s2[j]=s1[j];
for(int j=len;j>=1;j--)
{
s2[j-1]+=s2[j]%k*P;
s2[j]/=k;
}
len2=len;
while(!s2[len2]&&len2>1) len2--;
MAX();
}
while(!s3[len3]&&len3>1) len3--;
printf("%d",s3[len3]);
for(int i=len3-1;i>=1;i--)
printf("%04d",s3[i]);
//printf("\ntime:%.2lf",clock()/1000.0);
return 0;
}