题解 | #替换空格#
剪绳子
http://www.nowcoder.com/practice/57d85990ba5b440ab888fc72b0751bf8
{
//说实话这是一道数学题目= =,首先最重要的问题是确认分绳子的最优解法。
//-----------------------------------------------------
//数学方法
//设绳子总长度为y,剪成了a段(暂时不考虑剪后是否为整数的问题)。
//y=n1+n2+...+na
//其乘积S为n1·n2·...·na,由均值不等式(n1+n2+n3+...+na)/a 等于 y/a 大于等于 (n1·n2·n3·...·na)^(1/a)得:
//当且仅当每一个项相等时,不等式等号成立,乘积取得最大值。所以这道题的关键就变成寻找这个相等的值x到底是多少。
//将上述推论进行基本的变形,得到S=x^a,由于a=y/x,得S=x^(y/x)
//将S=x^(y/x)的两边取对数ln,并同时对x求微分并求x。为什么要这样做呢?首先这里y是绳子长度,可以理解为它是一个常数,我们要求乘积最大值,必须对这个方程进行求导,寻找这个方程的极点。
//求导后化简得(lnS')/S=y*(1-lnx)/x^2,令等式右边为0,解得x=e。那么意思就是,当绳子每段长度为自然底数e时,取得乘积S的最大值。
//但是x必须是整数,所以对e两侧的2和3分别进行测算,明显取3时更优。
//-----------------------------------------------------
//所以每段绳子的长度最好是3,这里有几种特殊情况:
//1.绳子正好被3等分,不讨论
//2.绳子尽可能的拆成长度为3的段后,剩下长度为1的一段。很明显最后乘一个1是不科学的,这时候就少取一段长度为3的绳子,将它和1组成长度为4的绳子,再拆成2*2的两段。
//3.绳子尽可能的拆成长度为3的段后,剩下长度为2的一段。这时候拆成两个1没有意义,所以不再拆分
//此外考虑长度为2和3的绳子,分别直接返回1和2即可
if(number===2){return 1}
if(number===3){return 2}
const remainder = number % 3//余数判断
if( remainder===0 ){
const pow = number/3;
return Math.pow(3,pow)
}
if(remainder===1){
const pow = (number-4)/3;
return Math.pow(3,pow)*4
}
if(remainder===2){
const pow = (number-2)/3;
return Math.pow(3,pow)*2;
}
}
module.exports = {
cutRope : cutRope
};