classSolution{publicintcuttingRope(int n){if(n <=3){return n -1;}int[] dp =newint[n +1];// 1. 初始化
dp[1]=1;
dp[2]=2;
dp[3]=3;for(int i =4; i <= n; i++){int max =0;for(int j =1; j <= i /2; j++){// 2. 状态转移方程
max =Math.max(max, dp[j]* dp[i - j]);}
dp[i]= max;}return dp[n];}}
2. 最优解:数学方法 O(n)、O(1)
见注释的正确性证明
主要做法就是循环地切出3,直到所剩值不大于4为止( n == 4 时候,直接用是最好的,因为 x * 4 == x* 2 * 2 > x * 3 * 1)
classSolution{publicintcuttingRope(int n){// 数学方法:O(n) & O(1)if(n <4){return n -1;}int res =1;// 循环切除3while(n >4){
res *=3;
n -=3;}// 最后乘一次 1 or 2 or 3 or 4return res * n;}}/*
* 正确性证明(参考评论区大佬)
* 1. 任何大于1的数都可由 2 & 3 组成(偶数可2累加,奇数就是前一个偶数加一次3)
* 2. 2 * 2 == 1 * 4 ,且 2 * 3 > 1 * 5,因此拆成2 & 3得到积最大
* 3. 因为 2 * 2 * 2 < 3 * 3,因此拆成 3 性价比最高
*/
二刷
结论题,记住循环切3就行
注意边界,n < 4 时直接取 n - 1
classSolution{publicintcuttingRope(int n){if(n <4){return n -1;}int ans =1;while(n >4){
n -=3;
ans *=3;}return n * ans;}}
剪绳子 II
题目描述
相较于1,多了一个取模操作
思路 && 代码
classSolution{publicintcuttingRope(int n){if(n <4){return n -1;}long res =1L;while(n >4){
res *=3;
res %=1000000007;
n -=3;}return(int)(res * n %1000000007);}}
二刷
注意涉及取模,直接用Long,防止溢出
classSolution{publicintcuttingRope(int n){if(n <4){return n -1;}long ans =1L;while(n >4){
ans *=3;
ans %=1000000007;
n -=3;}return(int)(ans * n %1000000007);}}