【题意】

恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右

手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n位大臣排

成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每

位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右

手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,

使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

【算法】贪心(排序)+高精度

【题解】这是少数不用二分解决最大值最小化问题的题。

我们考虑将所有大臣按某种条件排序,从而满足该顺序最优。

考虑当前已有排序,其中某两位置是a1,b1和a2,b2,交换两个位置不能使答案最优需要满足的条件。

显然交换两位置对前后都没有影响,假设Σai=s,所以交换后不能使答案最优须满足:

$$max(\frac{s}{b_1},\frac{sa_1}{b_2})<max(\frac{s}{b_2},\frac{sa_2}{b_1})$$

将s提出来,

$$max(\frac{1}{b_1},\frac{a_1}{b_2})<max(\frac{1}{b_2},\frac{a_2}{b_1})$$

由于ai是正整数,故我们已知:

$$\frac{1}{b_1}<\frac{a_2}{b_1} \ \ ,\ \ \frac{1}{b_2}<\frac{a_1}{b_2}$$

所以条件转化为:

$$\frac{a_1}{b_2}<\frac{a_2}{b_1}$$

即:

$$a_1b_1<a_2b_2$$

所以只要按aibi从小到大排序,一定最优。

为了找到适合排序的关键字,我们考虑某两位的交换会使排序更优的条件即可得知。

答案最大可以达到10000^1000即10^4000,要用高精度。(这是NOIP最后一次考高精度,以后不可能再考了)

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=,maxlen=;
struct cyc{int a,b,c;}a[maxn];
int n,lens,x,lmax,lena;
int sum[maxlen],ans[maxlen],maxs[maxlen];
bool cmp(cyc a,cyc b)
{return a.c<b.c;}
void cheng(int numi)
{
int num=a[numi].a;x=;
for(int i=;i<=lens;i++)
{
x+=sum[i]*num;
sum[i]=x%;
x/=;
}
while(x>)sum[++lens]=x%,x/=;
// printf("1...%d * lens=%d\n",numi,lens);
// for(int i=1;i<=lens;i++)printf("%d",sum[i]);printf("\n");
}
void divs(int numi)
{
int num=a[numi].b;x=;
for(int i=lens;i>=;i--)
{
x=x*+sum[i];
ans[i]=x/num;
x%=num;
}
lena=lens;
while(ans[lena]==&&lena>)lena--;
// printf("1...%d-1/%d / lens=%d\n",numi,numi,lena);
// for(int i=1;i<=lena;i++)printf("%d",ans[i]);printf("\n");
bool f=;
if(lena>lmax)f=;else if(lena<lmax)f=;else
for(int i=lena;i>=;i--)
if(ans[i]>maxs[i]){f=;break;}else if(ans[i]<maxs[i]){f=;break;}
if(!f)
{
for(int i=;i<=lena;i++)maxs[i]=ans[i];
lmax=lena;
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n+;i++)scanf("%d%d",&a[i].a,&a[i].b),a[i].c=a[i].a*a[i].b;
sort(a+,a+n+,cmp);//for(int i=1;i<=n+1;i++)printf("%d %d\n",a[i].a,a[i].b);
sum[(lens=)]=;cheng();maxs[(lmax=)]=;
for(int i=;i<=n+;i++)divs(i),cheng(i);
for(int i=lmax;i>=;i--)printf("%d",maxs[i]);
return ;
}

最新文章

  1. AngularJS-Uncaught Error: [$injector:modulerr]
  2. 20130625修改hbase的hbase-env导致导出器导出数据的速度变慢
  3. C++ 面向对象编程
  4. QCopChannel的用法
  5. form表单验证2
  6. ios9下ionic框架报[$rootScope:infdig] 10 $digest() iterations reached. Aborting!的解决办法
  7. Crontab设置定时任务
  8. composer 常用命令
  9. [BZOJ 1036] [ZJOI2008] 树的统计Count 【Link Cut Tree】
  10. linux 下载安装tomcat
  11. FileProvider解决FileUriExposedException
  12. spring的依赖注入是什么意思
  13. Nginx 多域名配置
  14. Spring框架最简单的定时任务调用
  15. C# ms speech文字转语音例子
  16. C#发起HTTP请求
  17. C#6.0语言规范(十二) 数组
  18. JQ面试问题(转载)
  19. linux svn配置与使用
  20. 最小生成树 - 普里姆 - 边稠密 - O(N ^ 2)

热门文章

  1. Java常用类之File类
  2. SERVER 2008 R2 SP1下的内存虚拟盘(支持32位,64位的所有windows版本)
  3. html 怎么去掉网页的滚动条
  4. windows下apache+php安装
  5. .NET环境下,通过LINQ操作SQLite数据库
  6. Calendar简单用法
  7. [OS] 进程间通信--管道
  8. veeValidate
  9. FreeBSD查看网络情况
  10. BZOJ2301:[HAOI2011]Problem b——题解