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


  • 相关阅读:
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    linux中的cd ..和cd -命令有什么区别?
    GCC使用
  • 原文地址:https://www.cnblogs.com/csnd/p/12062427.html
Copyright © 2011-2022 走看看