动态规划使用场景:求最优解、最大值、最小值等。
解决动态规划问题,一般从上往下分析,自下而上解决。
题目要求
思路分析
- 创建数组 dp,其中 dp[i] 表示将正整数 i 拆分成至少两个正整数的和之后,这些正整数的最大乘积; 其中,dp[0] = 0 、dp[1] = 1;
- 先把绳子剪掉第一段 j ,如果只减长度1,并不能得到最大乘积,所以从2开始剪,初始化dp[ 2 ] = 1;
- 剪了第一段 j 后,剩下的 i - j 长度可以剪也可以不剪。如果不剪,最大乘积为 j * (i - j);如果继续剪,最大乘积为 j * dp[ i - j ](转化为求剩下 i - j 的最大乘积)。取这两个方式的最大值 Math.max( j * (i - j),j * dp[ i - j ] );
- 第一段长度 j 可以取的区间为[ 2,i ],对所有 j 不同的情况取最大值,所以,长度为 i 的绳子,最终取的最大值为 dp[ i ] = Math.max(dp[ i ],Math.max( j * (i - j),j * dp[ i - j ] ));
- 最终调用返回dp[n]的值即可;
步骤
- 绳长为 i,第一次剪掉长度为 j,剩余长度( i - j )分两种情况考虑;
- 剩余长度不继续剪,最大乘积为 j * (i - j);
- 剩余长度继续剪,最大乘积为 j * dp[i - j];
- 此时最大值为 nowMax = Math.max(j * (i - j),j * dp[i - j]);
- 由于 j 的取值为1~ i-1,所以需要遍历 j,得到dp[ i ]的最大值
- 第一段长度 j 可取的区间为 [1,i-1],对所有 j 不同的情况也取最大值,则 dp[ i ] = Math.max(dp[ i ],Math.max( j * (i - j),j * dp[ i - j ] ));
Code part
var cuttingRope = function(n) {
let dp = new Array(n+1).fill(0),nowBigger;
dp[2] = 1;
//如果只剪掉长度1,乘积并不是最大,所以从2开始
for(let i = 2;i <= n;i++){
for(let j = 1;j < i;j++){
//剪了第一段后,剩下(i-j)可以剪,也可以不剪;
//不剪长度乘积:j * (i - j)
//继续剪,长度乘积:j * dp[i - j]
nowBigger = Math.max(j * (i - j),j * dp[i - j]);
//对于同一个i,内层循环对不同的j还会再拿到一个max,所以每层内循环都要更新max
dp[i] = Math.max(dp[i],nowBigger)
}
}
return dp[n];
};