题目:
中等 通过率:35.66% 时间限制:1秒 空间限制:64M
知识点基础数学
描述
给你一根长度为 n 的绳子,请把绳子剪成整数长的 m 段( m 、 n 都是整数, n > 1 并且 m > 1 , m <= n ),每段绳子的长度记为 k[1],...,k[m] 。请问 k[1]*k[2]*...*k[m] 可能的最大乘积是多少?例如,当绳子的长度是 8 时,我们把它剪成长度分别为 2、3、3 的三段,此时得到的最大乘积是 18 。
数据范围:2≤n≤60
进阶:空间复杂度 O(1),时间复杂度 O(n)
输入描述:
输入一个数n,意义见题面。
返回值描述:
输出答案。
示例1
输入:
8
复制返回值:
18
说明:
8 = 2 +3 +3 , 2*3*3=18
示例2
输入:
2
返回值:
1
说明:
m>1,所以切成两段长度是1的绳子
分析:
1、动态规划:
① n <=1时,不可分,乘积为0;
②n = 2时,只能分为 1-1 ,乘积为1。
③n=3时,分为1-2, 乘积最大为2。
④n=4时,分为2-2,乘积最大为4;
⑤n>=5时,乘积最大值与前面最大值有关,关系为:dp[i] = max( dp[i-j] * j )
长度n | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
乘积 | 0 | 1 | 2 | 3 | dp[2]*2=4 | dp[3]*2=6 | dp[3]*3=9 | dp[5]*2=12 |
2、归纳:
由,求 的最大值,代入得出 ,即求最大值
取对数得:
求导得: ==》
另 ,即 , 得出
, 介于 2 与 3之间
①对于8,分解为 3*3*2 = 18 大于 分解为 2*2*2*2 = 16。应优先分解为3.
②对于3,分解为2*2 大于 3*1, 因此对于最后一个3应当分解为2*2。
代码:
1、动态规划:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @return int整型
*/
int cutRope(int n) {
if(n <= 3) return n-1;
// write code here
vector<int> dp(n+1,0);
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
dp[4] = 4;
for(int i = 5 ; i <= n; i++)
for(int j = 1; j < i; j++)
dp[i] = max(dp[i], j * dp[i - j]);
return dp[n];
}
};
2、归纳:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @return int整型
*/
int cutRope(int n) {
if(n <= 3) return n -1;
// 幂:pow(底数,指数)
int m = n / 3, residue = n % 3;
if(residue == 1) return pow(3, m-1) * 2 * 2 ;
if(residue == 0) return pow(3, m);
return pow(3, m) * residue;
}
};