Description
恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人左手上数乘积除以他自己右手上的数, 然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获奖赏最多的大臣,所尽可能少。 注意,国王的位置始终在队伍最前面。
Input
第一行包含一个整数 n ,表示大臣的人数 。
第二行包含两个整数 a 和 b ,之间用一个空格隔开,分别表示国王左手和右上的整数。
接下来 n 行,每行包含两个整数 a 和 b ,之间用一个空格隔开,分别表示每大臣左手和右手上的整数。
Output
输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得金币数。
Sample Input
3
1 1
2 3
7 4
4 6
Sample Output
2
Key To Problem
简单的一道贪心加高精度,前六十分二十分钟就过去的,结果最后的高精度却调了一上午,真是惭愧
首先我们需要将这个序列排序,保证其为最优序列
则此序列满足到第i个大臣时a1∗a2∗a3∗...∗ai−1bi比其他顺序的赏赐要小
于是我们可以列出如下不等式
a1∗a2∗a3∗...∗ai−1bi<a2∗a3∗a4∗...∗aib1
a1∗a2∗a3∗...∗ai−1bi<a1∗a3∗a4∗...∗aib2
…
所以
a1∗b1∗(a2∗a3∗...∗ai−1)<(a2∗a3∗...∗ai−1)∗ai∗bi
a2∗b2∗(a1∗a3∗a4∗...∗ai−1)<(a1∗a3∗a4∗...∗ai−1)∗ai∗bi
…
由此可得
a1∗b1<ai∗bi
a2∗b2<ai∗bi
…
这也就是说当序列满足 ai∗bi>ax∗bx(x<i)时,此序列为最优序列
那也就是说我们要将大臣按照ai∗bi从小到大的顺序排序,那么贪心的思想就出来了
高精度写的很烂,一百多行的代码,简直就不忍直视
CODE
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define N 1010
#define MOD 100000000
using namespace std;
typedef long long ll;
typedef struct num
{
ll k[N];
int len;
}p;
struct node
{
int left,right;
};
node king;
node sec[N];
int n;
int cmp(const void *x,const void *y)
{
struct node a=*(struct node *)x;
struct node b=*(struct node *)y;
return a.left*a.right-b.left*b.right;
}
p max(p x,p y)
{
if(x.len!=y.len)
return x.len>y.len?x:y;
for(int i=x.len;i>=1;i--)
if(x.k[i]!=y.k[i])
return x.k[i]>y.k[i]?x:y;
return x;
}
p exchange(p x)
{
p y;
for(int i=1;i<=x.len;i++)
y.k[x.len-i+1]=x.k[i];
y.len=x.len;
return y;
}
p mul(p x,int y)
{
p z;
memset(z.k,0,sizeof(z.k));
for(int i=1;i<=x.len;i++)
{
z.k[i]+=x.k[i]*y;
z.k[i+1]=z.k[i]/MOD;
z.k[i]%=MOD;
}
z.len=x.len;
if(z.k[x.len+1]!=0)
z.len++;
return z;
}
p div(p x,int y)
{
p z;
memset(z.k,0,sizeof(z.k));
for(int i=1;i<=x.len;i++)
{
z.k[i]=x.k[i]/y;
x.k[i+1]+=(x.k[i]%y)*MOD;
}
z.len=x.len;
if(!z.k[1])
{
for(int i=1;i<=x.len;i++)
z.k[i]=z.k[i+1];
z.len--;
}
return z;
}
void print(p x)
{
printf("%d",x.k[1]);
for(int i=2;i<=x.len;i++)
printf("%08d",x.k[i]);
printf("\n");
}
int main()
{
// freopen("game.in","r",stdin);
// freopen("game.out","w",stdout);
scanf("%d%d%d",&n,&king.left,&king.right);
for(int i=1;i<=n;i++)
scanf("%d%d",&sec[i].left,&sec[i].right);
qsort(sec+1,n,sizeof(sec[0]),cmp);
p ans;
p sum;
memset(sum.k,0,sizeof(sum.k));
memset(ans.k,0,sizeof(ans.k));
ans.len=sum.len=1;
sum.k[1]=king.left;
for(int i=1;i<=n;i++)
{
sum=exchange(sum);
p s=div(sum,sec[i].right);
ans=max(ans,s);
sum=exchange(sum);
sum=mul(sum,sec[i].left);
}
print(ans);
return 0;
}