高精毒瘤题

考虑贪心。

对于两个大臣 \(i\)\(j\),当 \(a_i \times b_i <a_j \times b_j\) 时,\(i\) 排在 \(j\) 前更优 ### 证明: 因为所有大臣排成一列,所以我们考虑其中两个的关系,就可以推广到所有大臣。 我们还是取两个大臣 \(i\)\(j\),他们前面的人左手上的积为 \(x\),假设 \(i\) 在前面更优,则有: \[ans_1=\max(\frac{x}{b_i},\frac{x\times a_i}{b_j})\]\(j\) 在前面更优,则有 \[ans_2=\max(\frac{x}{b_j},\frac{x\times a_j}{b_i})\] 显然有 \[\frac{x}{b_i} \le \frac{x\times a_j}{b_i},\frac{x}{b_j}\le\frac{x\times a_i}{b_j}\] 若令 \(ans_1 < ans_2\),则必然有 \[\frac{x\times a_i}{b_j}<\frac{x\times a_j}{b_i}\] 化简,得 \[a_i \times b_i < a_j \times b_j\] 证毕。

code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1010;
int n,a,b;
struct node{
int a,b;
}e[N];
bool operator<(node x,node y){
return x.a*x.b<y.a*y.b;
}
struct ll{
int num[N*5];
int len;
ll(){
memset(num,0,sizeof(num));
len=0;
return;
}
void operator=(int x){
while(x){
num[++len]=x%10;
x/=10;
}
return;
}
bool operator<(const ll &x)const{
if(this->len<x.len)
return 1;
if(this->len>x.len)
return 0;
for(int i=len;i;i--){
if(this->num[i]<x.num[i])
return 1;
if(this->num[i]>x.num[i])
return 0;
}
return 1;
}
ll operator*(const int &x)const{
ll ans;
ans.len=this->len;
for(int i=1;i<=this->len;i++){
ans.num[i]+=this->num[i]*x;
ans.num[i+1]=ans.num[i]/10;
ans.num[i]%=10;
}
if(ans.num[ans.len+1]){
int k=ans.num[ans.len+1];
while(k){
ans.len++;
ans.num[ans.len]=k%10;
k/=10;
}
}
return ans;
}
bool operator<(const int &x)const{
int k=x,len1=0;
while(k){
k/=10;
len1++;
}
if(len1>this->len)
return 1;
if(len1<this->len)
return 0;
k=x;
for(int i=1;i<=n;i++){
if(this->num[i]<k%10)
return 1;
if(this->num[i]>k%10)
return 0;
k/=10;
}
return 0;
}
ll operator/(const int &x)const{
ll ans;
if(*this<x)
return ans;
ans.len=this->len;
int k=0;
for(int i=this->len;i;i--){
k=k*10+this->num[i];
ans.num[i]=k/x;
k%=x;
}
while(!ans.num[ans.len])
ans.len--;
return ans;
}
};
void print(ll x){
if(x.len==0){
printf("0");
return;
}
for(int i=x.len;i;i--)
printf("%d",x.num[i]);
return;
}
ll max1(ll x,ll y){
if(x<y)
return y;
return x;
}
ll cnt,ans1;
int main(){
scanf("%d%d%d",&n,&a,&b);
cnt=a;
for(int i=1;i<=n;i++)
scanf("%d%d",&e[i].a,&e[i].b);
sort(e+1,e+1+n);
for(int i=1;i<=n;i++){
ans1=max1(ans1,cnt/e[i].b);
cnt=cnt*e[i].a;
}
print(ans1);
return 0;
}