P1080 国王游戏

题目描述

恰逢 \(H\)国国庆,国王邀请\(n\)位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 \(n\) 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

输入输出格式

输入格式:

第一行包含一个整数\(n\),表示大臣的人数。

第二行包含两个整数 \(a\)和 \(b\),之间用一个空格隔开,分别表示国王左手和右手上的整数。

接下来 \(n\)行,每行包含两个整数\(a\) 和 \(b\),之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

输出格式:

一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

输入输出样例

输入样例#1:

3
1 1
2 3
7 4
4 6

输出样例#1:

2

说明

【输入输出样例说明】

按11、22、33 这样排列队伍,获得奖赏最多的大臣所获得金币数为 22;

按 11、33、22 这样排列队伍,获得奖赏最多的大臣所获得金币数为22;

按 22、11、33 这样排列队伍,获得奖赏最多的大臣所获得金币数为 22;

按22、33、11这样排列队伍,获得奖赏最多的大臣所获得金币数为99;

按 33、11、22这样排列队伍,获得奖赏最多的大臣所获得金币数为 22;

按33、22、11 这样排列队伍,获得奖赏最多的大臣所获得金币数为 99。

因此,奖赏最多的大臣最少获得 22个金币,答案输出 22。

【数据范围】

对于 20%的数据,有 1≤ n≤ 10,0 < a,b < 81≤n≤10,0<a,b<8;

对于 40%的数据,有1≤ n≤20,0 < a,b < 81≤n≤20,0<a,b<8;

对于 60%的数据,有 1≤ n≤1001≤n≤100;

对于 60%的数据,保证答案不超过 10^9109;

对于 100%的数据,有 1 ≤ n ≤1,000,0 < a,b < 100001≤n≤1,000,0<a,b<10000。

NOIP 2012 提高组 第一天 第二题


思路

我们假设一个正确的序列中有两个元素 i 与 i + 1,他们左右手的数字分别为Ai,Bi,Ai+1,Bi+1

排在i大臣前面的所有人的左手上的数的乘积为T(以下向下取整省略不写)

这两位大臣得到最多的硬币为 max( T / Bi, (T * Ai) / Bi+1 ) = Ans1

假设交换这两位大臣 则他们得到最多硬币数变为 max( T / Bi+1, (T * Ai+1) / Bi ) = Ans2

要求Ans1 <= Ans2,原序列顺序可能不是最优(否则这两位大臣交换能得到更有策略)

所以要使 T / Bi 和 (T * Ai) / Bi+1都小于等于Ans2即可满足要求

由于T / Bi <= (T * Ai+1) / Bi ,T / Bi 肯定能满足要求,只要使 ( T * Ai ) / Bi+1 也小于等于 Ans2即可

(T * Ai) / Bi+1 肯定大于等于 T / Bi+1 ,所以只能使 (T * Ai+1) / Bi 大于等于(T * Ai) / Bi+1 ,否则不能达到要求

然后我们就可以列出不等式 (T * Ai) / Bi+1 <= (T * Ai+1) / Bi

因为T是正数,所以可以同时消去

Ai / Bi+1 <= Ai+1 / Bi

同乘Bi+1Bi

Ai * Bi <= Ai+1 * Bi+1

所以,只要按Ai * Bi从小到大排序就不成问题了。(当然别把国王也排序了)

注意要加高精度。

代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 10005 struct ppp{
int a, b;
}p[MAXN]; int n; bool cmp( ppp x, ppp y ){
return x.a * x.b < y.a * y.b;
} int s[4005], len;
int ans[4005], ans_l(0); void Mul( int x ){
int t(len);
for ( int i = 1; i <= len; ++i ) s[i] *= x;
for ( int i = 1; i <= len + 5; ++i ){
if ( s[i] ) t = i;
s[i + 1] += s[i] / 10;
s[i] %= 10;
}
len = t;
} void Copy( int c[], int c_l ){
for ( int i = 1; i <= c_l; ++i ) ans[i] = c[i];
ans_l = c_l;
} void Out( int s[], int l ){
for ( int i = l; i >= 1; --i ) printf( "%d", s[i] );
putchar('\n');
}
void Div( int x ){
int c[4005], l(-1);
for ( int i = 1; i <= len; ++i ) c[i] = s[i];
for ( int i = len; i >= 1; --i ){
c[i - 1] += ( c[i] % x ) * 10;
c[i] /= x;
if ( c[i] && l == -1 ) l = i;
}
if ( ans_l == l ){
bool flg(0);
for ( int i = l; i >= 1; --i )
if ( ans[i] < c[i] ){ flg = 1; break; }
else break;
if ( flg ) Copy( c, l );
}
if ( ans_l < l ) Copy( c, l );
} int main(){
scanf( "%d", &n );
scanf( "%d%d", &p[0].a, &p[0].b );
for ( int i = 1; i <= n; ++i ) scanf( "%d%d", &p[i].a, &p[i].b );
sort( p + 1, p + n + 1, cmp );
s[1] = 1; len = 1;
Mul( p[0].a );
for ( int i = 1; i <= n; ++i )
Div( p[i].b ), Mul( p[i].a );
Out( ans, ans_l );
return 0;
}

完事!!!

「洛谷P1080」「NOIP2012提高组」国王游戏 解题报告的更多相关文章

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

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

  2. 【noip2012提高组】国王游戏

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

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

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

  4. 洛谷P1003 铺地毯 noip2011提高组day1T1

    洛谷P1003 铺地毯 noip2011提高组day1T1 洛谷原题 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n ...

  5. 洛谷 P6570 - [NOI Online #3 提高组] 优秀子序列(集合幂级数+多项式)

    洛谷题面传送门 首先 \(3^n\) 的做法就不多说了,相信对于会状压 dp+会枚举子集的同学来说不算困难(暴论),因此这篇博客将着重讲解 \(2^nn^2\) 的做法. 首先如果我们把每个 \(a_ ...

  6. 洛谷-神奇的幻方-NOIP2015提高组复赛

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  7. 洛谷 P1541 乌龟棋 & [NOIP2010提高组](dp)

    传送门 解题思路 一道裸的dp. 用dp[i][j][k][kk]表示用i个1步,j个2步,k个3步,kk个4步所获得的最大价值,然后状态转移方程就要分情况讨论了(详见代码) 然后就是一开始统计一下几 ...

  8. 洛谷 P1525 关押罪犯 & [NOIP2010提高组](贪心,种类并查集)

    传送门 解题思路 很显然,为了让最大值最小,肯定就是从大到小枚举,让他们分在两个监狱中,第一个不符合的就是答案. 怎样判断是否在一个监狱中呢? 很显然,就是用种类并查集. 种类并查集的讲解——团伙(很 ...

  9. 洛谷 P5019 铺设道路 & [NOIP2018提高组](贪心)

    题目链接 https://www.luogu.org/problem/P5019 解题思路 一道典型的贪心题. 假设从左往右填坑,如果第i个深与第i+1个,那么第i+1个就不需要额外填: 如果第i+1 ...

随机推荐

  1. 云原生生态周报 Vol. 7 | Docker 再爆 CVE

    业界要闻 Docker 基础镜像 Alpine 爆出提权漏洞(CVE-2019-5021):该CVE影响自 Alpine Linux 3.3 版本开始的所有 Docker 镜像.该漏洞的机制在于 Al ...

  2. g++ 编译单个文件和多个文件

    转载:https://www.cnblogs.com/battlescars/p/cpp_linux_gcc.html 1.单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp ...

  3. Android本地数据存储: Reservoir

    一:前言 今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名.密码这样的.其实大家都知道,这种情况最常用的就是SharedPreferences了,我也不例外,脑子里第一个想到的就是用 ...

  4. Flex AIR应用拍照功能(Android和IOS版本)

    说明: 使用AIR处理拍照后的回调.照片文件的保存功能时,针对于IOS和Android两个平台是有所不同的. 但.关于如何调用摄像头进行拍照这个功能,Android和IOS是一致的. 技术实现: 1) ...

  5. Python--day47--mysql慢日志记录

  6. P1034 台阶问题一

    题目描述 有 \(N\) 级的台阶,你一开始在底部,每次可以向上迈最多2级台阶(最少1级),问到达第 \(N\) 级台阶有多少种不同方式. 输入格式 一个正整数 \(N(\le 20)\) . 输出格 ...

  7. vuex 快速上手,具体使用方法总结(含使用例子)

    网上有关vuex的文章很多,但有些比较复杂,这篇文章能让你快速使用vuex: vuex 用处:管理全局状态(类似全局变量,每个组件都能访问到) vuex 用法: //下面是一个js文件,用最简单最全的 ...

  8. H3C配置Header进入用户视图的提示信息--系统视图

                      incoming:登录终端用户界面时的提示信息. Header 3种类型     login:登录验证时的提示信息.    Vty模式                ...

  9. 【38.96%】【hdu 1540】Tunnel Warfare

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission ...

  10. Linux 内核存取 I/O 和内存空间

    一个 PCI 设备实现直至 6 个 I/O 地址区. 每个区由要么内存要么 I/O 区组成. 大部分 设备实现它们的 I/O 寄存器在内存区中, 因为通常它是一个完善的方法(如同在" I/O ...