NOIP2012day1 國王遊戲(貪心)
阿新 • • 發佈:2018-11-06
題意
https://www.luogu.org/problemnew/show/P1080
思路
按氣泡排序的原則,先分析兩兩是否交換的情況:
假設大臣
和大臣
,前面的大臣左手邊數的成績為常數
:
當
排在前面時,最大值是
;
當
排在前面時,最大值是
;
假設
在前面更優,就是
.
提出
,即為
.
又
所以原式又化簡成
交叉一下就是
這個時候貪心決策就比較明顯了,直接按
的乘積排序即可,範圍比較大,需要壓
位高精。
程式碼
#include<bits/stdc++.h>
#define FOR(i,x,y) for(register int i=(x);i<=(y);++i)
#define DOR(i,x,y) for(register int i=(x);i>=(y);--i)
#define N 1003
typedef long long LL;
using namespace std;
int n;
struct node{int a,b;}s[N];
bool cmp(node x,node y){return x.a*x.b<y.a*y.b;}
struct BigInt
{
int num[2003],n;
void clr(){memset(num,0,sizeof(num));n=0;}
void operator =(int x)
{
clr();
do
{
num[n++]=x%10000;
x/=10000;
}while(x);
}
BigInt operator /(const int &x)const
{
BigInt res;
res=(*this);
DOR(i,n-1,1)
{
res.num[i-1]+=(res.num[i]%x)*10000;
res.num[i]/=x;
}
res.num[0]/=x;
while(n>1&&res.num[res.n-1]==0)res.n--;
return res;
}
bool operator <(const BigInt &_)const
{
if(n!=_.n)return n<_.n;
DOR(i,n-1,0)if(num[i]!=_.num[i])return num[i]<_.num[i];
return false;
}
void operator *=(const int &x)
{
FOR(i,0,n-1)num[i]*=x;
FOR(i,0,n-1)
{
num[i+1]+=(num[i]/10000);
num[i]%=10000;
if(num[n])n++;
}
}
void Print()
{
printf("%d",num[n-1]);
DOR(i,n-2,0)printf("%04d",num[i]);
}
};
void chk_max(BigInt &x,BigInt y){if(x<y)x=y;}
int main()
{
scanf("%d",&n);
FOR(i,0,n)scanf("%d%d",&s[i].a,&s[i].b);
sort(s+1,s+1+n,cmp);
BigInt sum,ans;
sum=s[0].a,ans=0;
FOR(i,1,n)
{
chk_max(ans,sum/s[i].b);
sum*=s[i].a;
}
ans.Print();
return 0;
}