1. 程式人生 > 遊戲資訊 >死亡擱淺島剪版 遊戲記錄 遊戲桌布 戰場攝影師【BT】一

死亡擱淺島剪版 遊戲記錄 遊戲桌布 戰場攝影師【BT】一

題目:劍指 Offer 14- I. 剪繩子
優質解答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]