题目描述–剪绳子1
思路分析
首先要分析出怎么切分是最优方案,显然和一定时,分成相等的数的乘积最大。用简单的数学归纳的思想可以发现,4对应2*2,5对应2x3,6对应3x3,7对应3x2x2,8对应3x3x2,显然分为3是最优选,然后是2。
由不等式也可解出极值点是e约为2.7,距离3最近。
动态规划
首先最直接会想到用动态规划的思想解题,先考虑切3,判断切3后的值是否大于dp中对应的值,依此向前填充dp矩阵,然后考虑切2
int cuttingRope(int n) {
if(n < 4){
return n - 1;
}
vector<int> resMat(n + 1);
resMat[2] = 1;
resMat[3] = 2;
//优先切出3最好,2次之,动态规划只需要考虑后面多切的一刀
for(int i = 4; i < n + 1; ++i){
if(i - 3 > resMat[i - 3]){
resMat[i] = 3 * (i - 3);
}
else{
resMat[i] = 3 * resMat[i - 3];
}
if(i - 2 > resMat[i - 2]){
resMat[i] = max(resMat[i], 2 * (i - 2));
}
else{
resMat[i] = max(resMat[i], 2 * resMat[i - 2]);
}
}
return resMat[n];
}
贪心思想
很简单,既然3最好就尽量多的切为3,判断n%3的值,为0,结果为3(n/3),为1,结果为4x3((n-4)/3),为2,结果为2x3^((n-2)/3)
int cuttingRope(int n) {
if(n < 4){
return n - 1;
}
//贪心算法,优先剪3
int res;
if(n % 3 == 0){
res = int(pow(3, n / 3));
}
else if(n % 3 == 2){
res = 2 * int(pow(3, (n - 2) / 3));
}
else if(n % 3 == 1){
res = 4 * int(pow(3, (n - 4) / 3));
}
return res;
}
题目描述–剪绳子2
思路分析
题目仅是将n的范围扩大了,这样显然带来了大数越界的问题,显然不能再用动态规划的思想求解,只能选择贪心算法,此题也就变成了一个快速幂求余的问题。
代码
int cuttingRope(int n) {
if(n < 4){
return n - 1;
}
const int modNumber = 1000000007;
//贪心,快速幂求余
long res;
if(n % 3 == 1){
res = 4 * quickM(3, int((n - 4) / 3)) % modNumber;
}
else if(n % 3 == 2){
res = 2 * quickM(3, int((n - 2) / 3)) % modNumber;
}
else{
res = quickM(3, int(n / 3));
}
return res;
}
//快速幂
long quickM(long base, int N){
long res = 1;
while(N > 0){
if(N & 1){
res *= base;
res %= 1000000007;
}
base *= base;
base %= 1000000007;
N >>= 1;
}
return res;
}