NOIP2012国王游戏

国王游戏

【题目分析】
看到数据的范围,只有40%数据是可以用二进制过的。然而这也打消我们暴力枚举的念头。
思路从枚举到了贪心。
如果相邻的两个大臣进行交换,对之后的区间的答案并不影响。
就要进行神奇的数学推导%&*%&……()&
推得—>如果

aibi<a(i+1)b(i+1)

那么答案会更优。
如果就这样也挺好,但为什么还要考我的臭臭的高精!!
后来又推了一个式子:
aibi+bi+1<a(i+1)b(i+1)+bi

交上去也AC了,不过时间长了不少。(是因为数据太水了吗?)
希望神犇指点。
【代码】

#define M 1005
#include
#include
#include
#include
#define P 10000
using namespace std;
struct node{
    int l,r;
}a[M];
bool cmp(node x,node y){
    int m1=x.l*x.r;
    int m2=y.l*y.r;
    if(m1!=m2)return m1return x.r>y.r;
}
struct Bint{
    int num[5005],sz;
    Bint(){
        memset(num,0,sizeof(num));
        sz=0;
    }
    Bint operator*(const Bint &x){
        Bint t;
        for(int i=0;ifor(int j=0;j1]+=t.num[i+j]/P;
                t.num[i+j]%=P;
            }
        }
        int SZ=sz+x.sz-1;
        if(t.num[SZ])SZ++;
        t.sz=SZ;
        return t;
    }
    Bint operator/(const int &x){
        Bint t;
        for(int i=0;iint an=0;
        for(int i=sz-1;i>=0;i--)
            if(i)t.num[i-1]+=(t.num[i]%x)*P;
        for(int i=sz-1;i>=0;i--)
            t.num[i]/=x;
        while(!t.num[t.sz-1]&&t.sz>1)t.sz--;
        return t;
    }
    bool operator>(const Bint &x)const{
        if(sz>x.sz)return 1;
        else if(szreturn 0;
        for(int i=sz-1;i>=0;i--){
            if(num[i]>x.num[i])return 1;
            else if(num[i]return 0;
        }return 0;
    }
    void Print(){
        printf("%d",num[sz-1]);
        for(int i=sz-2;i>=0;i--)printf("%04d",num[i]);
        puts("");
    }//事实证明,这个十分好用
}sum,ans;
int main(){
    int i,j,n;
    scanf("%d",&n);
    for(i=0;i<=n;i++)scanf("%d %d",&a[i].l,&a[i].r);
    sort(a+1,a+n+1,cmp);
    int k=a[0].l;
    int len=0;
    while(k){
        sum.num[len++]=k%P;
        k/=P;
    }sum.sz=len;
    for(i=1;i<=n;i++){
        Bint res=sum/a[i].r;
        if(res>ans)ans=res;
        Bint w;
        k=a[i].l,len=0;
        while(k){
            w.num[len++]=k%P;
            k/=P;
        }w.sz=len;
        sum=sum*w;
    }
    ans.Print();
    return 0;   
}

你可能感兴趣的:(NOIP复赛,贪心)