国王游戏(贪心+大数)

Posted zdragon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了国王游戏(贪心+大数)相关的知识,希望对你有一定的参考价值。

                                                   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 }

 

以上是关于国王游戏(贪心+大数)的主要内容,如果未能解决你的问题,请参考以下文章

国王游戏 贪心+高精度

国王游戏(微扰贪心加高精度)

[贪心][高精]P1080 国王游戏(整合)

114. 国王游戏高精度+贪心

国王游戏 2012年NOIP全国联赛提高组(贪心+高精)

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