剑指 Offer 14- I. 剪绳子
思路:数学
将长度为n的绳子切为a段:
n = n 1 + n 2 + ⋯ + n a n=n_1+n_2+\cdots+n_a n=n1+n2+⋯+na
等价于求解:
m a x ( n 1 × n 2 × ⋯ × n a ) max(n_1 \times n2 \times \cdots \times n_a) max(n1×n2×⋯×na)
数学推导:
- 以下公式是均值不等式,等号当且仅当 n 1 = n 2 = ⋯ = n a n_1=n_2=\cdots=n_a n1=n2=⋯=na时成立
设绳子按照x长度分为a段,则乘积为:
x a = x n x = ( x 1 x ) n x^a=x^{\frac{n}{x}}={(x^{\frac{1}{x}})}^n xa=xxn=(xx1)n
对
y
=
x
1
x
y=x^{\frac{1}{x}}
y=xx1进行求导,得到:
∂
ln
y
∂
x
=
∂
1
x
ln
x
∂
x
\frac{\partial \ln y}{\partial x}=\frac{\partial \frac{1}{x}\ln x}{\partial x}
∂x∂lny=∂x∂x1lnx
∂ y ∂ x = 1 − ln x x 2 x 1 x \frac{\partial y}{\partial x}=\frac{1-\ln x}{x^2}x^{\frac{1}{x}} ∂x∂y=x21−lnxxx1
当x=3,乘积最大
切分原则:
- 最优:3
- 次优:2.若最后一段长度为2,保留
- 最差:1。若最后一段绳长为1,将3+1分为2+2
class Solution {
public:
int cuttingRope(int n) {
if(n<=3) return n-1;
int b=n%3;
if(b==0) return pow(3,n/3);
else if(b==1) return pow(3,n/3-1)*4;
else return pow(3,n/3)*b;
}
};
时间复杂度 O(1)
空间复杂度 O(1)