NOIP2012 国王游戏

描述

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

格式

输入格式

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

输出格式

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

样例1

样例输入1[复制]

 
3 
1 1 
2 3 
7 4 
4 6 

样例输出1[复制]

 
2

限制

每个测试点1s

提示

对于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。

来源

Noip2012提高组复赛Day1T2

 
终于滚回来填坑了,高精度数组要开大点,我压位开500都还太小,查了好久的错。。。
重新更新了一遍高精度模板
 
国王游戏贪心证明:
设两人左右手的数字为(a,b)和(x,y),S为两人之前所有人左手数字的乘积
ans=max{(S*a)/y,(S*x)/b}
设(S*a)/y<(S*x)/b
显然a/y<x/b
即a*b<x*y
证毕
  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<iomanip>
  5 using namespace std;
  6 
  7 const int MAXN=1000;
  8 const int DLEN=4;
  9 const int WIDE=10000;
 10 class BigNum
 11 {
 12 public:
 13     int NUM[MAXN];
 14     int L;
 15     bool flag;
 16     BigNum(){memset(NUM,0,sizeof(NUM));L=1;flag=0;}
 17     BigNum(const BigNum &T){memcpy(NUM,T.NUM,sizeof(NUM));L=T.L;flag=T.flag;}
 18     BigNum(int n){memset(NUM,0,sizeof(NUM));NUM[0]=n;L=1;while(NUM[L-1]>=WIDE){NUM[L]+=NUM[L-1]/WIDE;NUM[L-1]%=WIDE;L++;}flag=0;}
 19 };
 20 
 21 void Input(string s,BigNum &T)
 22 {
 23     int k=1,num=0;
 24     memset(T.NUM,0,sizeof(int)*MAXN);T.L=0;
 25     for(int i=s.size()-1;i>=0;i--)
 26     {
 27         if(k==WIDE) T.NUM[T.L++]=num,num=0,k=1;
 28         num+=k*(s[i]-'0');
 29         k*=10;
 30     }
 31     if(num>0) T.NUM[T.L++]=num;
 32 }
 33 
 34 void Output(const BigNum T)
 35 {
 36     if(T.flag==1) cout<<'-';
 37     cout<<T.NUM[T.L-1];
 38     for(int i=T.L-2;i>=0;i--)
 39     {
 40         cout.width(DLEN);
 41         cout.fill('0');
 42         cout<<T.NUM[i];
 43     }
 44 }
 45 
 46 bool cmp(const BigNum A,const BigNum B)
 47 {
 48     if(A.L!=B.L) return A.L<B.L;
 49     for(int i=A.L-1;i>=0;i--)
 50         if(A.NUM[i]!=B.NUM[i])
 51             return A.NUM[i]<B.NUM[i];
 52     return 0;
 53 }
 54 
 55 /*BigNum Add(const BigNum A,const BigNum B)
 56 {
 57     BigNum C;
 58     int L=max(A.L,B.L);C.L=L;
 59     for(int i=0;i<L;i++)
 60     {
 61         C.NUM[i]+=A.NUM[i]+B.NUM[i];
 62         if(C.NUM[i]>=WIDE)
 63             C.NUM[i]-=WIDE,C.NUM[i+1]++;
 64     }
 65     if(C.NUM[L]>0) C.L++;
 66     return C;
 67 }
 68 
 69 BigNum Add(const BigNum A,int B)
 70 {
 71     BigNum C(A);
 72     C.NUM[0]+=B;
 73     for(int i=0;i<C.L;i++)
 74         if(C.NUM[i]>=WIDE)
 75             C.NUM[i]-=WIDE,C.NUM[i+1]++;
 76     if(C.NUM[C.L]>0) C.L++;
 77     return C;
 78 }
 79 
 80 BigNum Dec(BigNum A,BigNum B)
 81 {
 82     BigNum *X=&A,*Y=&B,C;
 83     int L=max(X->L,Y->L);
 84     C.L=L;
 85     if(cmp(*X,*Y)) swap(X,Y),C.flag=1;
 86     for(int i=0;i<L;i++)
 87     {
 88         C.NUM[i]+=X->NUM[i]-Y->NUM[i];
 89         if(C.NUM[i]<0)
 90             C.NUM[i]+=WIDE,C.NUM[i+1]--;
 91     }
 92     while(C.NUM[C.L-1]==0) C.L--;
 93     return C;
 94 }
 95 
 96 BigNum Mult(const BigNum A,const BigNum B)
 97 {
 98     BigNum C;
 99     for(int i=0;i<A.L;i++)
100         for(int j=0;j<B.L;j++)
101         {
102             C.L=i+j;
103             C.NUM[C.L]+=A.NUM[i]*B.NUM[j];
104             if(C.NUM[C.L]>=WIDE)
105                 C.NUM[C.L+1]+=C.NUM[C.L]/WIDE,C.NUM[C.L]%=WIDE;
106         }
107     C.L=A.L+B.L;
108     if(C.NUM[C.L-1]==0) C.L--;
109     return C;
110 }*/
111 
112 BigNum Mult(const BigNum A,int B)
113 {
114     BigNum C(A);
115     int i,tmp,k=0;
116     for(i=0;i<C.L||k;i++)
117     {
118         tmp=C.NUM[i]*B+k;
119         k=tmp/WIDE;
120         C.NUM[i]=tmp%WIDE;
121     }
122     C.L=i;
123     return C;
124 }
125 
126 /*BigNum Div2(const BigNum A)
127 {
128     BigNum C(A);
129     for(int i=C.L-1;i>=0;i--)
130     {
131         if(C.NUM[i]%2&&i>0)
132             C.NUM[i-1]+=WIDE;
133         C.NUM[i]/=2;
134     }
135     if(C.NUM[C.L-1]==0) C.L--;
136     return C;
137 }
138 
139 BigNum Div(const BigNum A,const BigNum B)
140 {
141     BigNum L(1),R(A),T;
142     while(cmp(Add(L,1),R))
143     {
144         T=Div2(Add(L,R));
145         if(cmp(A,Mult(T,B)))
146             R=T;
147         else 
148             L=T;
149     }
150     return L;
151 }*/
152 
153 BigNum Div(const BigNum A,int B)
154 {
155     BigNum C(A);
156     int k=0;
157     for(int i=C.L-1;i>=0;i--)
158     {
159         k=k*WIDE+C.NUM[i];
160         C.NUM[i]=k/B;
161         k%=B;
162     }
163     while(C.NUM[C.L-1]==0) C.L--;
164     return C;
165 }
166 
167 const int MAXN_=1000+10;
168 struct Num
169 {
170     int L,R;
171 }T[MAXN_];
172 int n;
173 BigNum x=1,maxn=1;
174 BigNum t;
175 
176 bool cmp_(Num A,Num B)
177 {
178     return A.L*A.R<B.L*B.R;
179 }
180 
181 int main()
182 {
183     cin>>n;
184     cin>>T[0].L>>T[0].R;
185     for(int i=1;i<=n;i++)
186         cin>>T[i].L>>T[i].R;
187     sort(&T[1],&T[n+1],cmp_);
188     for(int i=1;i<=n;i++)
189     {
190         x=Mult(x,T[i-1].L);
191         t=Div(x,T[i].R);
192         if(cmp(maxn,t))
193             maxn=t;
194     }
195     Output(maxn);
196     return 0;
197 }

 

posted @ 2016-11-01 19:57  InWILL  阅读(365)  评论(0编辑  收藏  举报