• [NOIp2012] 国王游戏


    传送门:>Here<

    题意:有$N$个大臣,第$i$个大臣的左手写着$a_i$,右手写着$b_i$。一个大臣得到的金币为$$所有排在他前面的大臣左手写的数字的乘积除以他自己右手的数字。问如何排列大臣们的顺序,使得到金币最多那个大臣得到的最少。$(n leq 10^3)$

    解题思路

    这是一个跟顺序有关的问题。顺序问题在OI内不好解决,在数据范围小的情况一般采用状压DP,在这样的问题中一般考虑贪心。

    在顺序问题的贪心中,我们往往去考虑相邻的两个元素交换后答案的变化。即列出交换前和交换后的答案的表达式比较大小,使得交换后不比交换前优。得出的表达式就是排序的关键字了。事实上贪心严格的证明是要选取任意两个,但在推式子的时候很多时候选择相邻的两个会更好推,同时也能满足一样的性质。

    于是在这道题中,我们设两个相邻的大臣$i,j$。设$a_i$的前缀积为$c_i$,则有:

    交换前:前者得到$dfrac{c_{i-1}}{b_i}$,后者得到$dfrac{c_{j-1}}{b_j}$。

    交换后:前者得到$dfrac{c_{i-1}}{b_j}$,后者得到$dfrac{a_jc_{j-1}}{a_ib_i}$

    题目要求的是最大值最小,于是我们要令$max{dfrac{c_{i-1}}{b_i},dfrac{c_{j-1}}{b_j}} < max{dfrac{c_{i-1}}{b_j},dfrac{a_jc_{j-1}}{a_ib_i}}$

    由于$c$是单调的,前面的第二项一定大于后面的第一项。因此问题转化为比较前后两者的第二项大小。

    $dfrac{c_{j-1}}{b_j} < dfrac{a_jc_{j-1}}{a_ib_i}$,化简得$a_ib_i<a_jb_j$。这就是排序的关键字了。

    Code

    压位高精

    /*This Program is written by QiXingZhi*/
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector> 
    #include <cassert>
    #include <iostream>
    #include <string>
    using namespace std;  
      
    #define LL long long
    #define maxn 1010
    #define base 10000
    struct Bigint{
        int c[2020],len;
        Bigint(){memset(c,0,sizeof(c));len=1;}
        void Zero(){while(c[len]==0&&len>1)len--;}
        Bigint Write(char* s){
            memset(c,0,sizeof(c));len=1;
            int k=1,ll=strlen(s);
            for(int i=ll-1;i>=0;i--){
                c[len]+=(s[i]-'0')*k;
                k*=10;
                if(k==base){
                    k=1,len++;
                }
            }
            Zero();
            return *this;
        }
        void read(){
            char s[10020];
            scanf("%s",s);
            Write(s);
        }
        void Print(){
            Zero();
            printf("%d",c[len]);
            for(int i=len-1;i>=1;i--){
                printf("%04d",c[i]);
            }
        }
        bool operator >(Bigint& b){
            Zero();b.Zero();
            if(len!=b.len)return  len>b.len;
            for(int i=len;i>=1;i--){
                if(c[i]!=b.c[i])return c[i]>b.c[i];
            }
            return false;
        }
        bool operator <(Bigint& b){
            Zero();b.Zero();
            if(len!=b.len)return  len<b.len;
            for(int i=len;i>=1;i--){
                if(c[i]!=b.c[i])return c[i]<b.c[i];
            }
            return false;
        }
        Bigint operator = (const int& b){
            memset(c,0,sizeof(c)),len=1;
            char s[10020];
            sprintf(s,"%d",b);
            Write(s);
            return *this;
        }
        Bigint operator *(const int & b){
            Bigint r;
            r.len=len+4;
            for(int i=1;i<=r.len;i++){
                r.c[i]+=c[i]*b;
            }
            for(int i=1;i<=r.len;i++){
                r.c[i+1]+=r.c[i]/base;
                r.c[i]%=base;
            }
            r.Zero();
            return r;
        }
        Bigint operator / (const int& b){
            Bigint r,k;
            k=*this;
            r.len=len+1;
            for(int i=len;i>=1;i--){
                r.c[i]=k.c[i]/b;
                if(i!=1)k.c[i-1]+=(k.c[i]%b*base);
                k.c[i]/=b;
            }
            r.Zero();
            return  r;
        }
    }; 
    struct People{
        int a,b;
        Bigint mul;
    }p[1010];
    int N,A,B;
    Bigint ans,tot,x,y;
    inline bool cmp(const People& a, const People& b){
        x = a.mul, y = b.mul;
        return x < y;
    }
    int main(){
        scanf("%d",&N);
        scanf("%d %d",&A,&B);
        for(int i = 1; i <= N; ++i){
            scanf("%d %d",&p[i].a,&p[i].b);
            p[i].mul = p[i].a * p[i].b;
        }
        sort(p+1,p+N+1,cmp);
        ans = 0;
        tot = A;
        for(int i = 1; i <= N; ++i){
            if(tot/p[i].b > ans){
                ans = tot/p[i].b;
            }
            tot = tot * p[i].a;
        }
        ans.Print();
        return 0;
    } 
  • 相关阅读:
    2019-2020-2 网络对抗技术 20175217 Exp6 MSF基础应用
    2020_1课程设计—基于BC的证书格式转换工具的设计与实现—第二周进展
    2019-2020-2 网络对抗技术 20175217 Exp5 信息搜集与漏洞扫描
    2019-2020-2 网络对抗技术 20175217 Exp4 恶意代码分析
    2019-2020-2 网络对抗技术 20175205 Exp 9 Web安全基础
    2019-2020-2 网络对抗技术 20175205 Exp8 Web基础
    2019-2020-2 网络对抗技术 20175205 Exp7 网络欺诈防范
    2020_1课程设计—基于BC的证书格式转换工具的设计与实现—个人报告
    2020_1课程设计—基于BC的证书格式转换工具的设计与实现—Week3
    2019-2020-2 网络对抗技术 20175205 Exp6 MSF基础应用
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9483805.html
Copyright © 2020-2023  润新知