Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fc639a7

Browse files
committedOct 8, 2020
fix
1 parent b594413 commit fc639a7

File tree

1 file changed

+104
-17
lines changed

1 file changed

+104
-17
lines changed
 

‎docs/jzof/of014-i.md

Lines changed: 104 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,122 @@
1-
# OF14-I.剪绳子
1+
---
2+
description: 剑指 Offer 14- I. 剪绳子
3+
---
24

3-
> \[!WARNING\|style:flat\] This problem is temporarily not PR, please submit [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)
5+
# OF14-I.剪绳子
46

57
## 题目描述
68

7-
....
9+
[题目地址](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/)
10+
11+
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k\[0\],k\[1\]...k\[m-1\] 。请问 k\[0\]_k\[1\]_...\*k\[m-1\] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
12+
13+
### **示例 :**
14+
15+
```go
16+
输入: 2
17+
输出: 1
18+
解释: 2 = 1 + 1, 1 × 1 = 1
819

9-
**范例 :**
20+
输入: 10
21+
输出: 36
22+
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
1023

11-
```text
12-
Input: n=1
13-
Output: 1
24+
2 <= n <= 58
1425
```
1526

16-
## 题意
27+
### 标签:
1728

29+
* 动态规划
30+
* 数学
1831

32+
### 相似题目:
1933

20-
> ...
34+
\*\*\*\*[**343. 整数拆分**](https://leetcode-cn.com/problems/integer-break/)\*\*\*\*
2135

2236
## 题解
2337

24-
### 思路1
38+
### 思路1 : 动态规划
39+
40+
1. 对于的正整数 n,当 n≥2 时,可以拆分成至少两个正整数的和。令 k 是拆分出的第一个正整数,则剩下的部分是 n-k,n-k可以不继续拆分,或者继续拆分成至少两个正整数的和。由于每个正整数对应的最大乘积取决于比它小的正整数对应的最大乘积,因此可以使用动态规划求解。
41+
2. 创建数组 dp,其中 dp\[i\] 表示将正整数 ii 拆分成至少两个正整数的和之后,这些正整数的最大乘积。特别地,0 不是正整数,1是最小的正整数,0和1都不能拆分,因此dp\[0\]=dp\[1\]=0。
42+
3. 当 i≥2 时,假设对正整数 ii 拆分出的第一个正整数是j &lt; i , 1≤j&lt;i),则有以下两种方案:
43+
1. 将 ii 拆分成 j 和 i−j 的和,且 i-j不再拆分成多个正整数,此时的乘积是 j×\(i−j\)
44+
2. 将 i拆分成 jj 和 i-j的和,且 i-j 继续拆分成多个正整数,此时的乘积是 j×dp\[i−j\]
45+
4. 因此,当 j 固定时,有 dp\[i\] - max\(j\*\(i-j\) j\*dp\[i-j\]\)。由于 jj的取值范围是 1 到i−1,需要遍历所有的 j 得到 dp\[i\] 的最大值,因此可以得到状态转移方程如下:
46+
47+
$$
48+
dp[i] = max( max (j \times (i-j) , j \times dp[i-j]))
49+
$$
50+
51+
1. 最终得到 dp\[n\] 的值即为将正整数 n 拆分成至少两个正整数的和之后,这些正整数的最大乘积。
52+
53+
**复杂度分析:**
2554

26-
> ...
27-
>
28-
> ```go
29-
>
30-
> ```
55+
* **时间复杂度**$$O(1)$$****
56+
* **空间复杂度**$$O(1)$$****
57+
58+
#### 代码
59+
60+
{% tabs %}
61+
{% tab title="Go" %}
62+
```go
63+
func cuttingRope(n int) int {
64+
dp := make(map[int]int)
65+
dp[1] = 1 // 首项
66+
for i := 2; i < n+1; i++ {
67+
j, k := 1, i-1
68+
ans := 0
69+
for j <= k {
70+
ans = max(ans, max(j, dp[j])*max(k, dp[k])) // 递推公式
71+
j++
72+
k--
73+
}
74+
dp[i] = ans
75+
}
76+
return dp[n]
77+
}
78+
79+
func max(x int, y int) int {
80+
if x > y {
81+
return x
82+
}
83+
return y
84+
}
85+
```
86+
{% endtab %}
87+
88+
{% tab title="Python" %}
89+
```python
90+
class Solution:
91+
def cuttingRope(self, n: int) -> int:
92+
dp = [0] * (n + 1)
93+
for i in range(2, n + 1):
94+
for j in range(i):
95+
dp[i] = max(dp[i], j * (i - j), j * dp[i - j])
96+
return dp[n]
97+
```
98+
{% endtab %}
99+
100+
{% tab title="Java" %}
101+
```java
102+
class Solution {
103+
public int cuttingRope(int n) {
104+
int[] dp = new int[n + 1];
105+
for (int i = 2; i <= n; i++) {
106+
int curMax = 0;
107+
for (int j = 1; j < i; j++) {
108+
curMax = Math.max(curMax, Math.max(j * (i - j), j * dp[i - j]));
109+
}
110+
dp[i] = curMax;
111+
}
112+
return dp[n];
113+
}
114+
}
115+
```
116+
{% endtab %}
117+
{% endtabs %}
31118

32-
## 结语
119+
## 总结
33120

34-
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-algorithm](https://github.com/kylesliu/awesome-golang-algorithm)
121+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[awesome-golang-algorithm](https://github.com/kylesliu/awesome-golang-algorithm)
35122

0 commit comments

Comments
 (0)
Please sign in to comment.