题解 | #剪绳子(进阶版)#

剪绳子(进阶版)

https://www.nowcoder.com/practice/106f666170554379ab1974e5a601e741

class Solution {
public:
    //  // 迭代快速幂
    // long long fast(int a, int b)
    // {
    //     if (b == 0)  return 1;
    //     if (b%2 == 1) return a*fast(a, b-1)%998244353;
    //     else {
    //         long long tmp = fast(a,b/2);
    //         return (tmp*tmp)%998244353;
    //     } 
    // }

    // long long cutRope(long long number) {
    //     // write code here
    //     // 评论区有很多关于均值不等式最值证明,当剪每段3时候,乘积最大
    //     // 若一个一个相乘,乘积有点大,故快速幂解决  3^6 ==  3^3 x 3^3 ,瞬间从6次变成了乘以2次
    //     // if(number <= 4) return number;// 由于段数必须大于1,故这里不能这么写
    //     if(number == 2) return 1;
    //     if(number == 3) return 2;
    //     int count_3 = number/3;
    //     if (number%3 == 1) {//余数为1时,不改变整体,倒不如取个3凑成4更佳
    //         return 4*fast(3, count_3-1)%998244353;
    //     }
    //     else if(number%3 == 2)
    //     {
    //         return (2*fast(3, count_3))%998244353;
    //     }
    //     return fast(3, count_3);

    //     // 数据级太大了,不能用这个
    //     // vector<long long> dp(number+1, 0);
    //     // dp[1] = 1;
    //     // dp[2] = 2;
    //     // dp[3] = 3;
    //     // dp[4] = 4;
    //     // for(int i = 5; i <= number; ++i)
    //     // {
    //     //     for(int j = 1; j < i; ++j)
    //     //     {
    //     //         dp[i] = max(dp[i], j*dp[i-j]);
    //     //     }
    //     // }
    //     // return dp[number]%998244353; 
    // }
  // 我是写不出这种了。。。,谁会计算个数考虑使用二进制运算。。。
    long long mod = 998244353;
    //快速乘法
    long long fast(long long x, long long y){
        long long res = 0;
        x %= mod;
        y %= mod;
        while(y){
            if(y & 1){
                //加法代替乘法,防止越界
                res += x;
                if(res >= mod)
                    res -= mod;
            }
            y = y >> 1;
            x = x << 1;
            if(x >= mod)
                x -= mod;
        }
        return res;
    }
    //快速幂
    long long Pow(long long x, long long y){
        long long res = 1;
        while(y){
            //可以再往上乘一个
            if(y & 1)
                res = fast(res, x);
            //叠加
            x = fast(x, x);
            //减少乘次数
            y = y >> 1;
        }
        return res;
    }
    long long cutRope(long long number) {
        //不超过3直接计算
        if(number <= 3)
            return number - 1;
        //能整除3
        if(number % 3 == 0)
            return Pow(3, number / 3);
        //最后剩余1
        else if(number % 3 == 1)
            //4*3^{n-1}
            return fast(Pow(3, number / 3 - 1), 4);
        //最后剩余2
        else
            //2*3^n
            return fast(Pow(3, number / 3), 2);
    }
};

    

全部评论

相关推荐

shtdbb_:还不错,没有让你做了笔试再挂你
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务