剑指offer系列——67.剪绳子
Q:给你一根长度为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。
注意这里m>1
T:
1.贪心法
当n>=5时,3(n−3)>=2(n−2)且只在n取5时取等号,且它们都大于n,所以应把绳子剪成尽量多的3,让剩下的都是2这样的组合。
int cutRope(int len) {
if (len <= 0)
return 0;
else if (len <= 2)
return 1;
else if(len == 3)
return 2;
int i = len / 3;
int j = len % 3;
int m = 0;
if (j == 1) {
i -= 1;
m = 2;
} else if (j == 2) {
m = 1;
}
return (int) (pow(3, i) * pow(2, m));
}
2.动态规划法
\[f(n)=max(f(i)*f(n-i))
\]
int cutRope(int len) {
if (len <= 0)
return 0;
else if (len <= 2)
return 1;
else if (len == 3)
return 2;
int *product = new int[len + 1];
product[0] = 0;
product[1] = 1;
product[2] = 2;
product[3] = 3;
int max = 0;
for (int i = 4; i <= len; i++) {
max = 0;
for (int j = 1; j <= i / 2; j++) {
int pro = product[j] * product[i - j];
if (pro > max)
max = pro;
}
product[i] = max;
}
max = product[len];
delete[] product;
return max;
}