Math

题目描述[原题描述][https://www.acwing.com/problem/content/description/24/]

给你一根长度为 n绳子,请把绳子剪成 m段(mn都是整数,2≤n≤58 并且 m≥2)。

每段的绳子的长度记为k[0]、k[1]、……、k[m]。 可能的最大乘积是多少?

例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。

样例

1
2
3
输入:8

输出:18

算法描述

大佬题解(YXC)

首先把一个正整数 N拆分成若干正整数只有有限种拆法,所以存在最大乘积。
假设 N=n1+n2+…+nk,并且 n1×n2×…×nk是最大乘积。

  1. 显然1不会出现在其中;
  2. 如果对于某个 ini≥5,那么把 ni 拆分成3+(ni−3),我们有 3(ni−3)=3ni−9>ni
  3. 如果 ni=4,拆成 2+2乘积不变,所以不妨假设没有4;
  4. 如果有三个以上的2,那么 3×3>2×2×2,所以替换成3乘积更大;

综上,选用尽量多的3,直到剩下2或者4时,用2。

时间复杂度分析:当 n比较大时,n会被拆分成⌈n/3⌉个数,我们需要计算这么多次减法和乘法,所以时间复杂度是 O(n)。

C++代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int maxProductAfterCutting(int length) {
if(length<=3)return (length-1)*1;
int ans = 1;
if(length%3==1)ans = 4,length-=4;
else if(length%3 == 2)ans = 2,length-=2;
while(length){
ans*=3;
length-=3;
}
return ans;
}
};

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int maxProductAfterCutting(int length)
{
if(length==2)return 1;
if(length==3)return 2;
int ans=1;
if(length%3==1){
ans*=4;
length-=4;
}else if(length%3==2){
ans*=2;
length-=2;
}
while(length!=0){
ans*=3;
length-=3;
}
return ans;
}
}