zoukankan      html  css  js  c++  java
  • hdu4038贪心(最快上升倍率,好题)

    题意:
          给你n个数,然后有两种操作 1.给其中的一个数+1,2.在序列里面增加一个1,然后给你一个m,表示进行了m次操作,最后问你操作之后所有数乘积最大是多少?


    思路:
         徒弟给我的一个题目,感觉不错,这个题目细节比较多,至于难度,感觉还行,值得做一做,大体思路就是模拟,有点贪心的意思,首先我们要看看负数的个数,如果是奇数个,那么要把其中的一个绝对值最小的负数,也就是那个最大的负数变成正数,然后继续,如果是偶数个那么直接继续,接下来我们要把所有的0变成1,然后把所有的1变成2,然后把所有的2变成3,然后如果还有剩余步数,那么我们把他尽可能变成3,然后是2,如果这个时候还剩余怎么办?在剩余也就是肯定剩一个了,那么我们就把他加到当前的最小的那个数上,当前最小的那个数只有两种可能,要么是3,要么是比三大的数,这个自己想,上面的步骤中如果m在某个环节用没了,那么就停止然后统计答案就行了,下面说下,为什么3是关键呢?
    我的想法是这样,我们可以考虑增加的倍率,如果是0那么+1这个肯定是最优的,如果是1增加1也是当前最合适的,因为直接增加一倍,继续往下会发现到3的时候在增加就没有直接在虚拟出来一个3合适了,大体是下面那样
    1 > 0
    2/1 * 2/1 > 2
    3/2 * 3/2 * 3/2 > 3
    4/3*4/3*4/3*4/3 < 4
    我是这么推的 不知道对不对

    然后就是细节,各种细节要注意,比如3^X,这个X目测很大,为了不超时建议快速幂,还有就是数据范围,还有就是负数取余的问题...


    #include<stdio.h>
    #include<algorithm>
    
    #define MOD 1000000007
    
    __int64 X[100005];
    
    __int64 Pow(__int64 a ,__int64 b)
    {
        __int64 c = 1;
        while(b)
        {
            if(b&1) c = c * a % MOD;
            a = a * a % MOD;
            b /= 2;
            //printf("%I64d %I64d %I64d*
    " ,a ,b ,c);
        }
        return c;
    }
    
    int main ()
    {
        int t ,n ,cas = 1 ,i;
        __int64 m ,Ans;
        scanf("%d" ,&t);
        while(t--)
        {
            scanf("%d %I64d" ,&n ,&m);
            printf("Case %d: " ,cas ++);
            __int64 sf = 0 ,s0 = 0 ,s1 = 0 ,s2 = 0 ,s3 = 0;
            __int64 Max= 0 ,Maxid = -1;
            __int64 Min = 0 ,Minid = -1;
            for(i = 1 ;i <= n ;i ++)
            {
                scanf("%I64d" ,&X[i]);
                if(X[i] >= 3 && Minid == -1 || Min > X[i])
                {
                    Min = X[i];
                    Minid = i;
                }
                if(X[i] < 0)
                {
                    sf ++;
                    if(Max == 0 || Max < X[i])
                    Max = X[i] ,Maxid = i;
                }
                if(X[i] == 0) s0 ++;
                if(X[i] == 1) s1 ++;
                if(X[i] == 2) s2 ++;
            }
            if(sf % 2)
            {
                if(m <= -Max)
                {
                    X[Maxid] += m;
                    Ans = 1;
                    for(i = 1 ;i <= n ;i ++)
                    Ans = Ans * X[i] % MOD;
                    printf("%I64d
    " ,Ans);
                    continue;
                }
                s0 ++ ,m += Max;
            }
            else Maxid = -1;
            if(m >= s0)
            {
                s1 += s0;
                m = m - s0;
                s0 = 0;
            }
            else
            {
                s1 += m;
                s0 = s0 - m ;
                m = 0;
            }
    
            if(m >= s1)
            {
                s2 += s1;
                m = m - s1;
                s1 = 0;
            }
            else
            {
                s2 += m;
                s1 = s1 - m ;
                m = 0;
            }
            if(m >= s2)
            {
                s3 += s2;
                m = m - s2;
                s2 = 0;
            }
            else
            {
                s3 += m;
                s2 = s2 - m ;
                m = 0;
    
            }
            s3 += m / 3;
            s2 += m % 3 / 2;
            Ans = 1;
            if(m % 3 % 2)
            {
                if(s3)
                {
                    s3 --;
                    Ans = 4;
                }
                else
                for(i = 1 ;i <= n ;i ++)
                if(i == Minid) X[i] ++;
            }
            if(s0)
            {
                printf("0
    ");
                continue;
            }
            Ans = Ans * Pow(2 ,s2) % MOD * Pow(3 ,s3) % MOD;
            for(i = 1 ;i <= n ;i ++)
            {
                if(i == Maxid || X[i] == 0 || X[i] == 1 || X[i] == 2)
                continue;
                if(X[i] < 0) X[i] *= -1;
                Ans = Ans * X[i] % MOD;
            }
            printf("%I64d
    " ,Ans);
        }
        return 0;
    }
    


  • 相关阅读:
    常见水果的日语单词汇总
    身体各个部位的日语单词
    多拉A梦——日语歌词
    日语——动词的各种变形
    语言类型学分类
    常用自定义函数
    IOS 读取xib里的子控件
    IOS中 copy ,strong ,weak ,assign使用区别
    IOS 字典转模型
    IOS 纯代码添加 Button Image Label 添加到自定义View中
  • 原文地址:https://www.cnblogs.com/csnd/p/12062426.html
Copyright © 2011-2022 走看看