NOIP2012day1 国王游戏(贪心)

题意

https://www.luogu.org/problemnew/show/P1080

思路

按冒泡排序的原则,先分析两两是否交换的情况:
假设大臣 1 1 和大臣 2 2 ,前面的大臣左手边数的成绩为常数 c c
1 1 排在前面时,最大值是 max{cb1,ca1b2} max { c b 1 , c a 1 b 2 }
2 2 排在前面时,最大值是 max{cb2,ca2b1} max { c b 2 , c a 2 b 1 }
假设 1 1 在前面更优,就是 max{cb1,ca1b2}<max{cb2,ca2b1} max { c b 1 , c a 1 b 2 } < max { c b 2 , c a 2 b 1 } .
提出 c c ,即为 max{1b1,a1b2}<max{1b2,a2b1} max { 1 b 1 , a 1 b 2 } < max { 1 b 2 , a 2 b 1 } .
1b1a2b1,1b2a1b2 1 b 1 ≤ a 2 b 1 , 1 b 2 ≤ a 1 b 2
所以原式又化简成 a1b2<a2b1 a 1 b 2 < a 2 b 1
交叉一下就是 a1b1<a2b2 a 1 b 1 < a 2 b 2
这个时候贪心决策就比较明显了,直接按 a,b a , b 的乘积排序即可,范围比较大,需要压 4 4 位高精。

代码

#include
#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.bstruct 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(xint 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;
}

你可能感兴趣的:(题目)