Luogu 1080 【NOIP2012】国王游戏 (贪心,高精度)

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

Http

Luogu:https://www.luogu.org/problem/show?pid=1080

Source

贪心,高精度

题目大意

给出若干组二元组(a,b),对于一种排列方式,定义第i个二元组的花费为前面所有人的a之积除以第i个的b。现在要求求一种排列方式,使得其中最大的花费最小。

解决思路

我们来考虑排序方式。对于\(\forall\)两个人\(A,B\),设\(A\)的左手为\(A_l\),右手为\(A_r\),\(B\)同理。现在假设\(A与B\)是相邻的,他们前面的所有人的左手乘积为\(P\)。则有

顺序 A的花费 B的花费
A在前 \(\frac{T}{A_r}\) \(\frac{T*A_l}{B_r}\)
B在前 \(\frac{T*B_l}{A_r}\) \(\frac{T}{B_r}\)

那么我们如何排列\(A和B\)呢?那一定取决于上面表格中的两行中的最大值。而因为所有的数都是整数,所以我们可以知道\(\frac{T}{A_r}\)与\(\frac{T}{B_r}\)是不可能成为最大值的。

所以我们考虑\(\frac{T*A_l}{B_r}\)和\(\frac{T*B_l}{A_r}\)。

当\(\frac{T*A_l}{B_r} > \frac{T*B_l}{A_r}\)时,经过恒等变换,我们可以得到\(A_l*A_r>B_l*B_r\)也就是说,当A的左右手乘积大于B的左右手乘积时,我们把B排在前面会更优。

那么\(\frac{T*A_l}{B_r} < \frac{T*B_l}{A_r}\)是否也满足呢?我们发现是满足的。

也就是说,最优的排列方式为将人按照左右手乘积升序排序。至于求解其中的最大值,只要从1开始做一遍就可以啦。

最后需要注意的是,本题需要高精度。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; #define mem(Arr,x) memset(Arr,x,sizeof(Arr)) const int maxN=2000;
const int maxNum=5000;
const int inf=2147483647; #define ll long long class People//定义一个关于人的结构体,方便按照左右手乘积排序
{
public:
ll l,r;
}; bool operator < (People A,People B)//定义比较
{
return A.l*A.r<B.l*B.r;
} class BigInteger//定义高精度
{
public:
int siz;
ll Num[maxNum];
BigInteger();
BigInteger(int x);
BigInteger(ll x);
void operator = (int B);
bool operator == (int B);
bool operator == (BigInteger B);
BigInteger operator + (BigInteger B);
BigInteger operator * (ll B);
BigInteger operator / (ll B);
}; ostream& operator << (ostream & os,BigInteger A)//重载输出运算符方便输出
{
if (A.siz==0)
{
os<<0;
return os;
}
for (int i=A.siz;i>=1;i--)
os<<A.Num[i];
return os;
} bool operator < (BigInteger A,BigInteger B)//重载小于运算符
{
if (A.siz<B.siz)
return 1;
if (A.siz>B.siz)
return 0;
for (int ii=A.siz;ii>=1;ii--)
{
if (A.Num[ii]>B.Num[ii])
return 0;
if (A.Num[ii]<B.Num[ii])
return 1;
}
} ll n;
People P[maxN]; ll read(); int main()//主程序
{
n=read();
P[0].l=read();
P[0].r=read();
for (int i=1;i<=n;i++)
{
P[i].l=read();
P[i].r=read();
}
sort(&P[1],&P[n+1]);//将人排序
BigInteger ret=P[0].l;//ret即前面所有人左手的乘积
BigInteger Ans=0;//Ans记录最大的
for (int i=1;i<=n;i++)//依次计算
{
Ans=max(Ans,ret/P[i].r);
ret=ret*P[i].l;
}
cout<<Ans<<endl;
return 0;
} ll read()
{
ll x=0;
char ch=getchar();
while ((ch<'0')||(ch>'9'))
ch=getchar();
while ((ch>='0')&&(ch<='9'))
{
x=x*10+ch-48;
ch=getchar();
}
return x;
}
//以下就是高精度的重载
BigInteger::BigInteger()
{
siz=0;
mem(Num,0);
} BigInteger::BigInteger(int B)
{
siz=0;
mem(Num,0);
while (B!=0)
{
siz++;
Num[siz]=B%10;
B=B/10;
}
} BigInteger::BigInteger(ll B)
{
siz=0;
mem(Num,0);
while (B!=0)
{
siz++;
Num[siz]=B%10;
B=B/10;
}
} void BigInteger::operator = (int B)
{
siz=0;
mem(Num,0);
while (B!=0)
{
siz++;
Num[siz]=B%10;
B=B/10;
}
} bool BigInteger::operator == (BigInteger B)
{
if (siz!=B.siz)
return 0;
for (int ii=1;ii<=siz;ii++)
if (Num[ii]!=B.Num[ii])
return 0;
return 1;
} bool BigInteger::operator == (int B)
{
BigInteger A(B);
if (A==B)
return 1;
return 0;
} BigInteger BigInteger::operator + (BigInteger B)
{
BigInteger Ans;
Ans.siz=max(siz,B.siz);
for (int ii=1;ii<=Ans.siz;ii++)
Ans.Num[ii]=Num[ii]+B.Num[ii];
for (int ii=1;ii<Ans.siz;ii++)
{
Ans.Num[ii+1]+=Ans.Num[ii]/10;
Ans.Num[ii]%=10;
}
while (Ans.Num[Ans.siz]>=10)
{
Ans.Num[Ans.siz+1]+=Ans.Num[Ans.siz]/10;
Ans.Num[Ans.siz]%=10;
Ans.siz++;
}
return Ans;
} BigInteger BigInteger::operator * (ll B)
{
BigInteger Ans;
for (int ii=1;ii<=siz;ii++)
Ans.Num[ii]=1ll*Num[ii]*(ll)(B);
Ans.siz=siz;
for (int ii=1;ii<Ans.siz;ii++)
{
Ans.Num[ii+1]+=Ans.Num[ii]/10;
Ans.Num[ii]%=10;
}
while (Ans.Num[Ans.siz]>=10)
{
Ans.Num[Ans.siz+1]+=Ans.Num[Ans.siz]/10;
Ans.Num[Ans.siz]%=10;
Ans.siz++;
}
return Ans;
} BigInteger BigInteger::operator / (ll B)
{
BigInteger Ans;
int res=0;
for (int ii=siz;ii>=1;ii--)
{
res=res*10+Num[ii];
Ans.Num[ii]=res/B;
res=res%B;
}
Ans.siz=siz;
while (Ans.Num[Ans.siz]==0)
Ans.siz--;
return Ans;
}

Luogu 1080 【NOIP2012】国王游戏 (贪心,高精度)的更多相关文章

  1. [noip2012]国王游戏<贪心+高精度>

    题目链接: https://vijos.org/p/1779 https://www.luogu.org/problem/show?pid=1080 http://codevs.cn/problem/ ...

  2. 洛谷P1080(NOIP2012)国王游戏——贪心排序与高精度

    题目:https://www.luogu.org/problemnew/show/P1080 排序方法的确定,只需任取两个人,通过比较与推导,可以得出ai*bi小的人排在前面: 高精度写的时候犯了些细 ...

  3. 【NOIP2012提高组】国王游戏 贪心 + 高精度

    题目分析 题目答案不具有单调性,所以不可以二分,转而思考贪心.因为无法确定位置,所以考虑如何才能让对于每一个$1 ~ i$使得$i$的答案最大,即$1 ~ i$最后一个最优.若设对于位置$i$,$a[ ...

  4. P1080 国王游戏 贪心 高精度

    题目描述 恰逢 HH国国庆,国王邀请nn 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 nn 位大臣排成一排,国王站在队伍的 ...

  5. P1080 【NOIP 2012】 国王游戏[贪心+高精度]

    题目来源:洛谷 题目描述 恰逢 H国国庆,国王邀请n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王 ...

  6. Luogu P1080 [NOIP2012]国王游戏

    题目 按\(a_i*b_i\)升序排序即可. 证明考虑交换法. 对于排序后相邻的两个人\(i,j(a_ib_i\le a_jb_j)\),设前面的总的积为\(s\),则当前答案为\(\max(\fra ...

  7. Luogu P1080国王游戏(贪心)

    国王游戏 题目链接:国王游戏 ps:题目数据说明了要写高精度. 这个题的答案是\(a.l * a.r < b.l * b.r\)按照这个进行排序 题解中大部分只是如何证明排序是: \(a.l * ...

  8. NOIP2012 国王游戏

    2国王游戏 (game.cpp/c/pas) [问题描述] 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数 ...

  9. NOIP2012国王游戏(60分题解)

    题目描述 恰逢 H国国庆,国王邀请n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王站在队伍的最前面 ...

  10. 继续写高精!noip2012国王游戏。。。

    国王游戏 题目描述: 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王 ...

随机推荐

  1. 七年一冠、IG牛13的背后是什么!

    最近忙着看S8世界总决赛,博客荒废了近一个月,后续步入正轨.   2018年11月3日.S8世界总决赛.中国终于夺得了S系列赛的总冠军. “IG牛逼”也开始刷爆社交圈,对于在S3入坑的我来说,也弥补上 ...

  2. CSS 外边距

    CSS 外边距围绕在元素边框的空白区域是外边距.设置外边距会在元素外创建额外的“空白”. 设置外边距的最简单的方法就是使用 margin 属性,这个属性接受任何长度单位.百分数值甚至负值. ##### ...

  3. 破解Zip加密文件常用的几种方法

    前言 在互联网的浪潮中,大家也许碰到过这种情况: 从网络上下载了一个zip文件,最后却发现它是用密码保护的,或者自己用密码加密了一个很重要zip文件,但是一段时间后忘记了密码,无法打开.这个时候,我们 ...

  4. Spark Streaming简介及原理

    简介: SparkStreaming是一套框架. SparkStreaming是Spark核心API的一个扩展,可以实现高吞吐量的,具备容错机制的实时流数据处理. 支持多种数据源获取数据: Spark ...

  5. Centos7.3下安装Jumpserver 1.0.0(支持windows组件)

    Jumpserver最新版本支持windows组件,废话不多介绍了,下面直接介绍下部署过程: 0)系统环境 CentOS 7.3 IP: 192.168.10.210 [root@jumpserver ...

  6. SpringCloud设定Feign底层实现

    1. 概述 版本: spring-boot:  1.5.9.RELEASE spring-cloud: Dalston.SR5 在默认情况下 spring cloud feign在进行各个子服务之间的 ...

  7. VC++6.0的使用感想

    VC++6.0是我接触的第一款编程软件,一直以来都是使用这款软件来完成程序的编写,调试,运行.一直以来都是用C语言编写代码.而VC++6.0窗口简洁明了,占用资源少,上手容易,个人表示很喜欢. VC+ ...

  8. 软工个人博客作业Week 1

    问题1:在瀑布模型中提到模型,模型(模拟版本)和原型有什么不同,如果与原型有同样的功能,那为什么称之为模型?如果没有同样的功能,又是怎么测试那些程序的? 问题2:怎样才能高效率的广泛而深入地了解用户的 ...

  9. 《Gogoing》Alpha版会议总结

    一.开会的过程 首先大家对自己的任务进行了汇报,然后大家就当前最需要解决的问题提出解决方案,最后相互鼓励,相互帮助,探讨下一步该怎么做. 二.讨论的问题 百度地图API代码和界面代码为什么对接不上? ...

  10. 『编程题全队』"Gugua"事务管理系统项目宣传文案

    一.项目简介 1.项目简介 Gugua是为了解决有事务管理需要的人群的痛苦, 他们需要 一个便利和高效的个人和团体事务管理平台,但是现有的方案并没有很好地解决这些需求,我们有独特的办法是提供跨平台的软 ...