死亡擱淺島剪版 遊戲記錄 遊戲桌布 戰場攝影師【BT】一
阿新 • • 發佈:2022-04-02
題目:劍指 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}}\)
令\(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]