剪绳子
给你一根长度为 n 绳子,请把绳子剪成 m 段(m、n 都是整数,2≤n≤58 并且 m≥2)。
每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]k[1] … k[m] 可能的最大乘积是多少?
例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。
样例
输入:8
输出:18
思路
- 把一个正整数 N 拆分成若干正整数,只有有限种拆法N=n1+n2+…+nk,所以存在最大乘积。
- 为了求最大乘积,所以我们要避免拆出1。
- 假设ni > 5, ni 一定可以拆为 3 + (ni -3) = ni, 将3x(ni - 3)与ni做差,3x(ni - 3)-ni = 3ni - 9 - ni =2ni - 9.因为ni > 5,因此 一定有2ni - 9大于0,即 3 + (ni -3) > ni。所有,大于等于5的都会被往下拆成一个或多个3
- 假设ni为4,只能拆为2和2,因为不可能包含1,而 4=2*2,4没必要存在。以上证明N的拆分只可能包含2和3。并且最多两个2。
JS实现
// const len = 8
// const len = 4;
const len = 5;
const maxProductAfterCutting = function (length) {
if (length <= 3) { return 1*(length-1) } // 2≤ length ≤58 并且 m≥2
let multiple, surplus= length % 3;
// 0 => length能被3整除,
// 1 => length 可以拆分为2X2+一个3的倍数
// 2=> length 可以拆分为2+一个3的倍数
if (surplus === 0) { // length 可分为 K个3
multiple = Math.pow(3, Math.floor(length / 3));
} else if(surplus === 1) {
multiple = Math.pow(3, Math.floor(length / 3) - 1) * 4;
} else if(surplus === 2) {
multiple = Math.pow(3, Math.floor(length / 3)) * 2;
}
return multiple;
};
console.log(maxProductAfterCutting(len));