【LeetCode】剪绳子及其进阶版

剪绳子

题目表述

给你一根长度为 n 的绳子,请把绳子剪成整数长的 m 段( m 、 n 都是整数, n > 1 并且 m > 1 , m <= n ),每段绳子的长度记为 k[1],…,k[m] 。请问 $k[1] x k[2] x…x k[m] $可能的最大乘积是多少?例如,当绳子的长度是 8 时,我们把它剪成长度分别为 2、3、3 的三段,此时得到的最大乘积是 18 。

数据范围: 2 ≤ n ≤ 60 2 \le n \le 60 2n60
进阶:空间复杂度 O(1),时间复杂度 O(n)

示例

输入:
8
返回值:
18
说明:
8 = 2 +3 +3 , 2*3*3=18 

思路

  1. 根据 算术几何均值不等式 推导,将一个整数n均分成k个相同的数时,乘积最大;因此可以得知一个推论,最优情况下应是尽量将绳子切成k段相同的整数长度
  2. 假设绳子长度为n,将其分割成a段长度相同为x的绳子(可为非整数),则其表达式为 y = x a y=x^a y=xa, 其中 a = n / x a=n/x a=n/x,因此要求解的对象则为求 y = x 1 x y=x^{\frac{1}{x}} y=xx1的极大值点。通过y对x进行求导最终可以得知极大值点x=e。
  3. 此处e接近整数2,3;通过几次测试(比如将11分成2或者3)可以得知,当x=3时可以获得更大的乘积,因此确定最终的x为3
  4. 对绳子长度n分以下三种情况考虑:
    1. n%3=0: 可被3整除,最终乘积为 3 a 3^a 3a
    2. n%3=1: 余下一段绳子长度为1,由于此前绳子乘积乘上最终的1不会改变长度,因此可借助最后一段长度为3的绳子,将其分成2*2
    3. n%3=2:剩下的2保持完整不分割时乘积最大

—————————————————— 一条分割线————————————————

进阶版的剪绳子区别在于绳子的长度范围改变,在进阶版中,绳子的长度范围在 [ 2 , 2 14 ] [2,2^{14}] [2,214],因此直接调用pow函数计算3的指数次幂会超出long long类型的存储范围,因此需要在每次乘上3之后对答案进行求模(如998244353),防止答案过大。

那么在进行pow指数计算的时候,可以通过采取快速幂的方式来降低计算复杂度。

代码

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    long long fastpow(long long n, long long num){
        if(num==0){
            return 1;
        }
        if(num==1){
            return n;
        }
        long long part = fastpow(n,num/2);
        if(num%2){
            return (part*part*n)%998244353;
        }else{
            return (part*part)%998244353;
        }
    }
    long long cutRope(long long n) {
        // write code here
        //推论一:均分
        //推论二:每段尽量接近3
        if (n==2){
            return 1;
        }
        if(n==3){
            return 2;
        }
        long long a = n/3;
        long long b = n%3;
        if(b==0){
            return fastpow(3,a)%998244353;
        }else if(b==1){
            a--;
            return (fastpow(3,a)*4)%998244353;
        }else{
            return (fastpow(3,a)*b)%998244353;
        }
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值