剑指 Offer 14- I. 剪绳子

2022/4/4 23:22:39

本文主要是介绍剑指 Offer 14- I. 剪绳子,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题目:剑指 Offer 14- I. 剪绳子

image

优质解答1:数学推导(参考自K神)

由题知,\(n=n_1+...+n_m\),我们要求\(max(n_1\cdot n_2\cdot ... \cdot n_m)\),由算术几何均值不等式\(\frac{n_1 + n_2+...+n_m}{m}\geq \sqrt[m]{n_1n_2...n_m}\),等号在\(n_1=n_2=...=n_m\)处取得,所以当绳子均分时得到乘积最大,我们设每段长x,则有\(n=mx\),乘积为\(x^m\),令\(y=x^m=x^{\frac{n}{x}}=(x^{\frac{1}{x})^n}\),求此时的最大值等价于求\(y=x^{\frac{1}{x}}\)的最大值,两边取对数求导,

\[lny=\frac{1}{x}lnx\\ \frac{y'}{y}=\frac{1-lnx}{x^2}\\ y'=x^{\frac{1}{x}}\cdot \frac{1-lnx}{x^2} \]

令\(y'=0\),可得\(x=e\),当\(x<e\)时,\(y'>0\),函数递增;当\(x>e\)时,\(y'<0\),函数递减,\(x=e\)为极大值点。
因为x要取整数,所以x需要在2和3之间选一个,比较\(2^\frac{1}{2}\)和\(3^\frac{1}{3}\),同时乘六次方得\(2^3<3^2\),所以x取3时,函数值更大。
时间:\(O(N)\)
空间:\(O(1)\)

class Solution:
    def cuttingRope(self, n: int) -> int:
        # K神源码,时间O(1),空间O(1)
        if n <= 3: return n - 1
        a, b = n // 3, n % 3
        if b == 0: return int(math.pow(3, a))
        if b == 1: return int(math.pow(3, a - 1) * 4)
        return int(math.pow(3, a) * 2)
        # 参考自郁郁雨
        if n < 4:   return n - 1
        res = 1
        while n > 4:
            res *= 3
            n -= 3
        return res * n
优质解答2:动态规划

设置dp数组保存长度为0~n的最终结果,外循环代表绳子的长度,内循环代表最后一刀截的长度,如果为1则对乘积无影响,所以从2开始,截一刀之后需要看当前长度乘剩下的长度(未切)的乘积与当前长度乘剩下长度(切过)最大值的乘积的大小,然后再与完全不剪dp[i]作比较。

class Solution:
    def cuttingRope(self, n: int) -> int:
        dp = [0] * (n + 1)
        dp[2] = 1
        for i in range(3, n + 1):
            for j in range(2, i):
                dp[i] = max(dp[i], max(j * (i-j), j * dp[i-j]))
        return dp[n]


这篇关于剑指 Offer 14- I. 剪绳子的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程