国王游戏(贪心+大数)

                                                   4824: 国王游戏

时间限制(普通/Java):3000MS/9000MS     内存限制:65536KByte
总提交: 2            测试通过:1

描述

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

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

输入

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

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

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

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

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

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

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

输出

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

样例输入

3

1 1

2 3

7 4

4 6

样例输出

2

分析:先假设有两个大臣,国王左手为a0,右手为b0,大臣1左手为a1,右手为b1,大臣2左手为a2,右手为b2.

有两种排列方法:1.大臣1在前,最后答案为max(a0/b1,a0*a1/b2)

        2.大臣2在前,最后答案为max(a0/b2,a0*a2/b1)

不妨设大臣1在前为最后答案,然后推出关系式.

显然a0/b1<a0*a2/b1,a0/b2<a0*a1/b2,求得a0*a1/b2<a0*a2/b1,即a1*b1<a2*b2,因此排序按左右手乘积进行升序.

然后就是数据太大,需要大数运算.

还有考虑当最后那个大臣右手数字很大的时候,算的话会得出0,所以加个特判为0的时候输出1.

 1 #include <cstdio>
 2 #include <algorithm>
 3 #define jz 10000;
 4 using namespace std;
 5 struct one
 6 {
 7     int a,b;
 8 }p[1010];
 9 bool cmp(one a,one b) //按乘积升序
10 {
11     return a.a*a.b<b.a*b.b;
12 }
13 int a[10000]={0};
14 void mul(int a[],int n) //乘法
15 {
16     int t=0;
17     for(int i=0;i<10000;i++)
18     {
19         t+=a[i]*n;
20         a[i]=t%jz;
21         t/=jz;
22     }
23 }
24 void div(int a[],int n) //除法
25 {
26     int t=0;
27     for(int i=9999;i>=0;i--)
28     {
29         t=a[i]+t*jz;
30         a[i]=t/n;
31         t%=n;
32     }
33 }
34 int main()
35 {
36     int n;
37     one gw;
38     scanf("%d%d%d",&n,&gw.a,&gw.b);
39     for(int i=0;i<n;i++)
40         scanf("%d%d",&p[i].a,&p[i].b);
41     sort(p,p+n,cmp);
42     a[0]=gw.a;
43     for(int i=0;i<n-1;i++)
44         mul(a,p[i].a);
45     div(a,p[n-1].b);
46     int t=9999;
47     while(t>=0&&!a[t]) //注意下标,可能a数组都为0
48         t--;
49     if(t==-1) //当最终答案为0时,输出1
50     {
51         printf("1\n");
52         return 0;
53     }
54     printf("%d",a[t--]);
55     for(;t>=0;t--)
56         printf("%04d",a[t]);
57     putchar(10);
58 }

原文地址:https://www.cnblogs.com/zdragon1104/p/8423837.html

时间: 2024-10-15 03:46:19

国王游戏(贪心+大数)的相关文章

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

题目分析 题目答案不具有单调性,所以不可以二分,转而思考贪心.因为无法确定位置,所以考虑如何才能让对于每一个$1 ~ i$使得$i$的答案最大,即$1 ~ i$最后一个最优.若设对于位置$i$,$a[i]$表示左手,$b[i]$表示右手,$S$为其前面所有人的左手之积,那么他的答案就是$\frac{S}{b[i]}$,如果存在在$i$后边的$j$的答案更优, 即$\frac{S * a[i]}{b[j]} > \frac{S * a[j]}{b[i]} => a[i] * b[i] >

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

题目:https://www.luogu.org/problemnew/show/P1080 排序方法的确定,只需任取两个人,通过比较与推导,可以得出ai*bi小的人排在前面: 高精度写的时候犯了些细节错误,详见注释. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 200005 using namespace std;

# 国王游戏(贪心+大数乘除+微扰法证明)

国王游戏(贪心+大数乘除+微扰法证明) 题意:n个大臣和一个国王,左右手都有一个数,排队,国王始终拍在最前面,每个大臣的奖励为这个大臣前面的人的左手上的数之积除以这个大臣右手上的数.构造最优队伍,使得奖励最多的大臣的奖励最少. 证明: 微扰法的使用 我们现在将任意两个人的位置互换,然后考虑他们在交换前和交换后所获得的奖励是多少,其他人的奖励不变: 交换前: 第 \(i\) 个人是 : \(A_0 * A_1*....*A_{i-1}/B_i\) 第 \(i+1\) 个人是 : \(A_0 * A

【贪心+排序】国王游戏

[贪心+排序]国王游戏 Time Limit: 1000MS Memory Limit: 131072KB Description 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果. 国王不希

洛谷P1080 国王游戏 高精度 贪心 数学推公式

洛谷P1080 国王游戏        数学推公式      高精度    贪心 然而这并不是我打出来的,抄题解... 将左手与右手的乘积从小到大排序,然后计算求最大值即可.(需要高精度) 证明: 1)知道,如果相邻的两个人交换位置,只会影响到这两个人的值,不会影响他人 2)假设相邻的两个人i, i + 1.设A[i] B[i] <= A[i + 1] B[i + 1],i之前所有人的左手乘积为S. 则,ans1 = max{S / B[i], S * A[i] / B[i + 1]} 若交换

【NOIP 2012 国王游戏】 贪心+高精度

题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大臣,所获奖赏尽可能的少

luoguP1080 国王游戏 题解(NOIP2012)(贪心+高精)

luoguP1080 国王游戏 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define il inline #define rg register #define ll long long #define N 10001 #define inf 10000

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

P1080 国王游戏 题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大

AC日记——国王游戏 洛谷 P1080

国王游戏 思路: 贪心+高精: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 struct DataType { int a,b,key; bool operator<(const DataType pos)const { return key<pos.key; } }; struct DataType ai[maxn]; struct BintType { int len; char ch[