Leetcode 剑指 Offer 14- II. 剪绳子 II LCOF

11 篇文章 0 订阅
8 篇文章 0 订阅

题目链接:剪绳子 II LCOF

题目大意:给你一个绳子,长度为n,要求你拆分其为m(m>2)段,并且要求所有段长度的乘积最大

题目思路:比较经典的一个题目了,首先可以想到的一个经典解法是dp的做法,对于一个绳子,我们先任意减去一小段,这样得到的就是更小的绳子,而更小的绳子的最大乘积我们可以得到,因此就有了答案,枚举取最大值即可。
 而另一个解法涉及到到数学问题,这个做法的证明可以见官方题解,证明的很好,本质上是证明一个下界,比较容易想到的解法是长度为n的绳子拆分成m段,一定是均分后得到的乘积最大,而通过公式可以求导算出来,分为3的长度是最优的,所以直接用长度为3的来划分即可,其余部分采用快速幂解决,具体见代码

时间复杂度&&空间复杂度:O(log2n)&O(1)

DP做法:

class Solution {
public:
    long long dp[1005];
    const long long mod = 1e9+7;
    void pre(){
        dp[0] = 1;
        dp[1] = 1;
        for(long long i = 2;i <= 60;i++){
            long long maxx = -1;
            for(long long j = 1;j < i;j++){
                maxx = max(maxx,j*max(i-j,dp[i-j]));
            }
            dp[i] = maxx;
        }
    }
    int cuttingRope(int n) {
        pre();
        //for(int i = 1;i <= 10;i++) cout<<dp[i]<<endl;
        return dp[n];
    }
};

数学公式:

class Solution {
public:
    const int mod = 1e9+7;
    long long quick_mod(long long a,long long b){
        long long ans = 1;
        while(b){
            if(b&1) ans = ans*a%mod;
            a = a*a%mod;
            b>>=1;
        }
        return ans;
    }
    int cuttingRope(int n) {
        if(n == 2) return 1;
        else if(n == 3) return 2;
        if(n%3 == 0) return quick_mod(3,n/3);
        else if(n%3 == 1) return quick_mod(3,n/3-1)*4%mod;
        else return quick_mod(3,n/3)*2%mod;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值