*给你一根长度为 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。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
2 <= n <= 58
这个题呢,感觉是思路和找规律的题,首先我们这么看一下(2 <= n <= 58)
2:11
3:12
4:22 2+2
5:23 2+3
6:33 3+3
7:223 4+3
8:233 5+3
9:333 6+3
这样基本就可以看出规律了,
1.有3要取3,有2不影响,不能有1,有1加一个3转化为22
2.在7之后其实就是4的最优方法再乘上3,而4的最优方法又是2*2(从动态规划来说,可以得到f(n)=f(n-3)*3)
有了上面的发现之后,我们可以对3取余找到余数,再对3整除,余数可能出现3种情况
1.为0时,这是全部为3的情况,是最优的
2.为1时,有1出现是最差的,必须将整除的结果减一,也就是拿一个3出来再结合这个1转化为2和2,这样是就是最优的了
3.为2时,无需特殊转化,直接相乘即是最优的
最后通过总结出的这些规律和情况就可以得到结果了
要注意的是:n为2和3时是不满足上面的规律的,需要特判,因为他们只能被迫取1,整除中没有多余的3可以让他变为2和2
贴出代码:
class Solution {
/**
* @param Integer $n
* @return Integer
*/
function cuttingRope($n) {
if ($n == 2) {
return 1;
}
if ($n == 3) {
return 2;
}
$a = $n%3;
$b = intval($n/3);
$res = 1;
if ($a == 1) {
$b--;
$res *= 4;
} elseif ($a == 2) {
$res *= 2;
}
$res *= pow(3, $b);
return $res;
}
}