题目:洛谷P1080、Vijos P1779、codevs1198。

题目大意:国王和每个大臣左、右手各写了一个数。规定每个大臣得到的金币数为他前面所有人左手的数字的乘积除以他自己右手的数(向下取整),现在国王要改变大臣的排列顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少(国王永远站在最前面)。

解题思路:(贪心)首先,交换相邻两个大臣只会对这两个大臣造成影响,并不会对其他大臣造成影响。

我们考虑大臣i和i+1,设他们左手数字分别为A[i]和A[i+1],右手分别为B[i]和B[i+1],前i-1个大臣和国王左手的数的乘积为S,且A[i]B[i]<=A[i+1]B[i+1]。

原来两个大臣能得到的金币数分别为S/B[i],S*A[i]/B[i+1]。

如果交换,则第一个大臣现在能得到S*A[i+1]/B[i],第二个能得到S/B[i+1]。

由于A[i]B[i]<=A[i+1]B[i+1],所以S*A[i]*B[i]<=S*A[i+1]*B[i+1],所以S*A[i]/B[i+1]<=S*A[i+1]/B[i]。

由此可得大臣以A[i]B[i]从小到大排序,答案越小。

而S*A[i+1]/B[i]>=S/B[i],S*A[i]/B[i+1]>=S/B[i+1],故最大的答案为后面那个大臣的,也保证了答案的正确性。

然后高精度一下就好了。

C++ Code:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
struct BigInteger {
static const int BASE=100000000;
static const int WIDTH=8;
vector<long long>s;
BigInteger(long long num=0){*this=num;}
BigInteger operator = (long long num){
s.clear();
do{
s.push_back(num%BASE);
num/=BASE;
} while(num>0);
return *this;
}
BigInteger operator = (const string& str){
s.clear();
int x,len=(str.length()-1)/WIDTH+1;
for(int i=0;i<len;i++){
int end=str.length()-i*WIDTH;
int start=max(0,end-WIDTH);
sscanf(str.substr(start,end-start).c_str(),"%d",&x);
s.push_back(x);
}
return *this;
}
BigInteger operator + (const BigInteger& b)const{
BigInteger c;
c.s.clear();
for(int i=0,g=0;;i++){
if(g==0&&i>=s.size()&&i>=b.s.size())break;
int x=g;
if(i<s.size())x+=s[i];
if(i<b.s.size())x+=b.s[i];
c.s.push_back(x%BASE);
g=x/BASE;
}
return c;
}
bool operator < (const BigInteger& b)const{
if(s.size()!=b.s.size())return s.size()<b.s.size();
for(int i=s.size()-1;i>=0;i--)
if(s[i]!=b.s[i])return s[i]<b.s[i];
return false;
}
bool operator > (const BigInteger& b)const{return b<*this;}
bool operator <= (const BigInteger& b)const{return !(b<*this);}
bool operator >= (const BigInteger& b)const{return !(*this<b);}
bool operator != (const BigInteger& b)const{return b<*this||*this<b;}
bool operator == (const BigInteger& b)const{return !(b<*this)&&!(*this<b);}
void cheng(int a){
vector<long long>c;
for(int i=0;i<s.size();++i){
if(c.size()<=i)c.push_back(s[i]*a);else
c[i]+=s[i]*a;
if(c[i]/BASE)
if(c.size()<=i+1)c.push_back(c[i]/BASE);else
c[i+1]=c[i]/BASE;
c[i]%=BASE;
}
s=c;
}
void chu(int a){
vector<long long>c(s);
if(s.back()/a)c[s.size()-1]=s.back()/a,s[s.size()-1]%=a;else
c.pop_back();
for(int i=s.size()-2;i>=0;--i){
long long num=s[i+1]*BASE+s[i];
c[i]=num/a;
num%=a;
s[i]=num;
}
s=c;
}
};
ostream& operator << (ostream &out,const BigInteger& x){
out<<x.s.back();
for(int i=x.s.size()-2;i>=0;i--){
char buf[20];
sprintf(buf,"%08d",x.s[i]);
for(int j=0;j<strlen(buf);j++)out<<buf[j];
}
return out;
}
istream& operator >> (istream &in,BigInteger& x){
string s;
if(!(in>>s))return in;
x=s;
return in;
}
struct DC{
int a,b;
bool operator < (const DC&rhs)const{return a*b<rhs.a*rhs.b;}
}p[1005];
int n;
BigInteger sum,Div,ans;
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=0;i<=n;++i)cin>>p[i].a>>p[i].b;
sort(p+1,p+n+1);
sum=ans=p[0].a;
for(int i=1;i<=n;++i){
Div=sum;
Div.chu(p[i].b);
if(ans<Div)ans=Div;
sum.cheng(p[i].a);
}
cout<<ans<<endl;
return 0;
}

[NOIP2012提高组]国王游戏的更多相关文章

  1. GZOJ 1361. 国王游戏【NOIP2012提高组DAY1】

    国王游戏[NOIP2012提高组DAY1] Time Limit:1000MS Memory Limit:128000K Description 国王游戏(game.cpp/c/pas) [问题描述] ...

  2. 刷题总结——疫情控制(NOIP2012提高组)

    题目: 题目背景 NOIP2012 提高组 DAY2 试题. 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都 ...

  3. [NOIP2012] 提高组 洛谷P1080 国王游戏

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

  4. 洛谷P1080 [NOIP2012提高组D1T2]国王游戏 [2017年5月计划 清北学堂51精英班Day1]

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

  5. 「洛谷P1080」「NOIP2012提高组」国王游戏 解题报告

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

  6. NOIP2012 提高组 Day 1

    期望得分:100+100+70=270 实际得分:100+50+70=220 T2 没有底 最后剩余时间来不及打高精.思路出现错误 T1 Vigenère 密码 题目描述 16 世纪法国外交家 Bla ...

  7. [NOIP2012] 提高组 洛谷P1081 开车旅行

    题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...

  8. [NOIP2012] 提高组 洛谷P1084 疫情控制

    题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...

  9. [NOIP2012] 提高组 洛谷P1083 借教室

    题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然 ...

随机推荐

  1. C++线程安全退出

    HANDLE m_EvtThreadExit[MaxVisionNum]; //定义 方法一 ;i<MaxVisionNum;i++) m_EvtThreadExit[index] = Crea ...

  2. Html表单提交到Servlet输出到页面乱码

    Html使用的编码是UTF-8编码显示页面,之后使用form表单提交字段到Servlet中,Servlet将利用getParamer方法获得form提交的字段,之后通过Respone中的writer将 ...

  3. python购物车系统

    购物车系统模拟:product_list = [ ('java',100), ('python',200), ('键盘',500), ('电脑',4000), ('mac Book',7000),]S ...

  4. 斗地主算法的设计与实现(一)--项目介绍&如何定义和构造一张牌

    大学期间,我在别人的基础上,写了一个简易的斗地主程序. 主要实现了面向对象设计,洗牌.发牌.判断牌型.比较牌的大小.游戏规则等算法. 通过这个斗地主小项目的练习,提高了我的面向对象设计能力,加深了对算 ...

  5. 小A点菜 水题 dp 背包

    基本上还是01背包,首先注意必须正好花光钱,所以初始化时除了dp[0]以外其他都要设置成inf,然后因为求方案数,所以基本方程为dp[i] = dp[i-x] + dp[i],再根据inf进行一些特殊 ...

  6. Redis介绍以及安装具体解释

    redis是一个key-value存储系统. 和Memcached类似.它支持存储的value类型相对很多其它,包含string(字符串).list(链表).set(集合).zset(sorted s ...

  7. 一个leetcode解题报告类目,代码很简洁

    http://bookshadow.com/leetcode/ 里面的代码很简洁.可以看.

  8. 移动端页面弹出对话框效果Demo

    核心思路:设置一个隐藏的(display:none;).背景偏暗的div及其子div作为对话框.当点击某处时,将此div设置为显示. 核心代码例如以下(部分js代码用于动态调整div内容的行高.这部分 ...

  9. GraphicsMagick java.io.FileNotFoundException: gm 错误解决办法

    GraphicsMagick java.io.FileNotFoundException: gm 解决办法, 方法一: ProcessStarter.setGlobalSearchPath(" ...

  10. jsp页面中自定义标签的小演示

    在实习期遇到公司的pg自定义标签了,同事要我自己自学一下 自定义标签是用户定义的JSP语言元素.当JSP页面包含一个自定义标签时将被转化为servlet.JSP标签扩展可以让你创建新的标签并且可以直接 ...