1. 程式人生 > >NOIP2012day1 國王遊戲(貪心)

NOIP2012day1 國王遊戲(貪心)

題意

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

思路

按氣泡排序的原則,先分析兩兩是否交換的情況:
假設大臣 1 和大臣 2 ,前面的大臣左手邊數的成績為常數

c
1 排在前面時,最大值是 max { c
b 1 , c a 1 b 2
}

2 排在前面時,最大值是 max { c b 2 , c a 2 b 1 }
假設 1 在前面更優,就是 max { c b 1 , c a 1 b 2 } < max { c b 2 , c a 2 b 1 } .
提出 c ,即為 max { 1 b 1 , a 1 b 2 } < max { 1 b 2 , a 2 b 1 } .
1 b 1 a 2 b 1 , 1 b 2 a 1 b 2
所以原式又化簡成 a 1 b 2 < a 2 b 1
交叉一下就是 a 1 b 1 < a 2 b 2
這個時候貪心決策就比較明顯了,直接按 a , b 的乘積排序即可,範圍比較大,需要壓 4 位高精。

程式碼

#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;
}