[NOIP 2012 提高组] 国王游戏
2025/3/1
考虑贪心。
对于两个大臣 \(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:
#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;
}
本文作者:headless_piston
本文链接:https://www.cnblogs.com/headless-piston/p/18744489
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步