zoukankan      html  css  js  c++  java
  • 国王游戏

    传送门

    又是一道木有看题解就想出来的题

    题意:

    简而言之
    一堆数
    求排列
    使这些数
    经过操作后
    最大值最小

    解法:

    注意:根据题意每个数都有两个数a,b,这里为了方便记作一个数

    我们贪心的只考虑第n个数

    由于是乘积

    所以第n个数确定时

    前n-1个数a的乘积就是确定的

    所以可以先求出前n个数a的乘积mul

    则我们现在需要确定第n个数的值

    第n个数的值 即为前n个数a的乘积mul除以第n个数的a,b(都要除)

    所以第n个数我们选择a( imes)b最大的数

    前n-1个数a的乘积就变成mul(div)a

    在按照上面方法继续求n-1的数,n-2的数……

    求出所有数的值的最大值即为答案


    我们不妨证明一下这样做的正确性:

    若只有2个大臣

    国王、大臣 左、右手分别为(a_0 b_0,a_1 b_1,a_2 b_2)

    (a_1 imes b_1<a_2 imes b_2)

    那么
    若把(a_1,b_1)放第2个位置 答案即为max((frac{a_0}{b_2},frac{a_0a_2}{b_1}))
    若把(a_2,b_2)放第2个位置 答案即为max((frac{a_0}{b_1},frac{a_0a_1}{b_2}))

    易得
    (frac{a_0a_2}{b_1}>frac{a_0a_1}{b_2},frac{a_0a_2}{b_1}gefrac{a_0}{b_1})

    所以把max((frac{a_0}{b_2},frac{a_0a_2}{b_1}))(ge)max((frac{a_0}{b_1},frac{a_0a_1}{b_2}))

    所以把(a_2,b_2)放第2个位置答案才能最小

    虽然只是证了两个数的情况

    但是若有更多数a的乘积其实可以看做上述式子(a_0)

    于是得到结论

    (a_i imes b_i)的值大的放后 答案才能最小

    证毕


    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<map>
    #define inf 100000000
    #define min(x,y) ((x)<(y)?(x):(y))
    #define max(x,y) ((x)>(y)?(x):(y))
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    int n;
    struct node
    {
        int a,b,ab;
    }dg[1010];
    
    const int p=1e4;
    struct hact
    {
        int arr[1000],len;
        hact()
        {
            memset(arr,0,sizeof(arr));
            len=0;
        }
        void print()
        {
            printf("%d",arr[len]);
            dwn(i,len-1,0)
            {
                printf("%04d",arr[i]);
            }
            putchar('
    ');
        }
    }ans,mul;
    hact operator *(hact a,int b)
    {
        if(b==0)
        {
            hact c;
            return c;
        }
        hact c;c.len=a.len;ll x=0;
        rep(i,0,c.len)
        {
            c.arr[i]=(1ll*a.arr[i]*b+x)%p;
            x=(1ll*a.arr[i]*b+x)/p;
        }
        while(x>0)
        {
            c.arr[++c.len]=x%p;
            x/=p;
        }
        return c;
    }
    hact operator /(hact a,int b)
    {
        hact c;c.len=a.len;ll x=0;
        dwn(i,c.len,0)
        {
            c.arr[i]=(a.arr[i]+x*p)/b;
            x=(a.arr[i]+x*p)%b;
        }
        dwn(i,c.len,1)
        {
            if(c.arr[i]==0) c.len--;
            else break;
        }
        return c;
    }
    hact arrmax(hact a,hact b)
    {
        if(a.len>b.len)
            return a;
        else if(a.len<b.len)
            return b;
        dwn(i,a.len,0)
        {
            if(a.arr[i]>b.arr[i]) return a;
            else if(a.arr[i]<b.arr[i]) return b;
        }
        return a;
    }
    bool cmp(node a,node b)
    {
        return a.ab<b.ab;
    }
    int main()
    {
        scanf("%d",&n);
        mul.arr[0]=1;
        rep(i,0,n)
        {
            scanf("%d%d",&dg[i].a,&dg[i].b);
            dg[i].ab=dg[i].a*dg[i].b;
            mul=mul*dg[i].a;
        }
        sort(dg+1,dg+n+1,cmp);
        dwn(i,n,1)
        {
            ans=arrmax(ans,mul/dg[i].ab);
            mul=mul/dg[i].a;
        }
        ans.print();
        return 0;
    }
    
    
  • 相关阅读:
    ES6 快速入门
    export,import ,export default区别
    React 生命周期
    Nodejs npm常用命令
    JavaScript:改变 HTML 图像
    WebStorm安装、配置node.js(Windows)
    Flex 布局
    块级元素与行内元素区别
    自动化测试弹框处理
    python远程操作服务器
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/10916245.html
Copyright © 2011-2022 走看看