CS-Notes/docs/notes/14. 剪绳子.md
2019-11-02 12:07:41 +08:00

53 lines
1.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 14. 剪绳子
[Leetcode](https://leetcode.com/problems/integer-break/description/)
## 题目描述
把一根绳子剪成多段并且使得每段的长度乘积最大
```html
n = 2
return 1 (2 = 1 + 1)
n = 10
return 36 (10 = 3 + 3 + 4)
```
## 解题思路
### 贪心
尽可能多剪长度为 3 的绳子并且不允许有长度为 1 的绳子出现如果出现了就从已经切好长度为 3 的绳子中拿出一段与长度为 1 的绳子重新组合把它们切成两段长度为 2 的绳子
证明 n >= 5 3(n - 3) - n = 2n - 9 > 0 2(n - 2) - n = n - 4 > 0因此在 n >= 5 的情况下将绳子剪成一段为 2 或者 3得到的乘积会更大又因为 3(n - 3) - 2(n - 2) = n - 5 >= 0所以剪成一段长度为 3 比长度为 2 得到的乘积更大
```java
public int integerBreak(int n) {
if (n < 2)
return 0;
if (n == 2)
return 1;
if (n == 3)
return 2;
int timesOf3 = n / 3;
if (n - timesOf3 * 3 == 1)
timesOf3--;
int timesOf2 = (n - timesOf3 * 3) / 2;
return (int) (Math.pow(3, timesOf3)) * (int) (Math.pow(2, timesOf2));
}
```
### 动态规划
```java
public int integerBreak(int n) {
int[] dp = new int[n + 1];
dp[1] = 1;
for (int i = 2; i <= n; i++)
for (int j = 1; j < i; j++)
dp[i] = Math.max(dp[i], Math.max(j * (i - j), dp[j] * (i - j)));
return dp[n];
}
```