题目
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
思路
- 假设绳子长度为n,可以逐个计算绳子长度为2、3、4…n-1时绳子分段的最大乘积。
- 用 f ( n ) f(n) f(n)表示长度为n的绳子最大乘积,则 f ( n ) = m a x ( f ( n − 1 ) , 2 f ( n − 2 ) , 3 f ( n − 3 ) , ⋯ ( n − 2 ) f ( 2 ) , ( n − 1 ) , 2 ( n − 1 ) , 3 ( n − 3 ) , ⋯ , ( n − 1 ) ) f(n)=max(f(n-1),2f(n-2),3f(n-3),\cdots (n-2)f(2),(n-1), 2(n-1),3(n-3),\cdots,(n-1)) f(n)=max(f(n−1),2f(n−2),3f(n−3),⋯(n−2)f(2),(n−1),2(n−1),3(n−3),⋯,(n−1))。
- 即n减去k,求k乘以长度为n-k的绳子的最大乘积。再计算将绳子分为两部分k和n-k的乘积。两者进行比较,k逐渐增大到n-1。
- 简单说,用res记录最大乘积, m a x ( r e s , k f ( n − k ) , k ( n − k ) max(res,kf(n-k),k(n-k) max(res,kf(n−k),k(n−k)
代码
class Solution {
public:
int cutRope(int number) {
if ( number < 1 ) return 0;
vector<int> dp(number+1, 0);
dp[1] = 1;
for ( int i = 2; i <= number; ++i ) {
for ( int j = 1; j < i; ++j ) {
dp[i] = max( max( dp[i], dp[i-j]*j ), (i-j)*j );
}
}
return dp[number];
}
};