剑指–剪绳子
1,题目:
2,思路:
方法一:这个是通过数字找规律的:
第一步:定义dp[n]的值的含义为:数字n的乘积最大值
n=2: 1+1 -->11=1; dp[2]=1;
n=3: 2+1 -->21=2; dp[3]=2;
n=4: 2+2 -->22=4; dp[4]=4;
n=5: 3+2 -->32=6; dp[5]=6;
貌似看不出规律,别急再多写几个
n=6: 3+3 -->33=9; dp[6]=9;
n=7: 4+3 -->43=12;–>dp[4]3=12 dp[7]=12;
n=8: 5+3 -->63=12;–>dp[5]3=18 dp[8]=18;
n=9: 6+3 -->93=12;–>dp[6]3=27 dp[9]=27;
n=10: 7+3 -->123=36;–>dp[7]*3=36 dp[10]=36;
第二步:找到递推的规律:
通过上述分析,规律明显在n=7以后为
if(n>=7)
dp[n] = dp[n-3]*3;
第三步:找初始值:
初始值在第二步找规律已经找到了
n=2: 1+1 -->11=1; dp[2]=1;
n=3: 2+1 -->21=2; dp[3]=2;
n=4: 2+2 -->22=4; dp[4]=4;
n=5: 3+2 -->32=6; dp[5]=6;
n=6: 3+3 -->3*3=4; dp[6]=9;
方法二:动态规划:
动态规划,每次都划分为f(i) * f(n-i),之前的值在dp数组已经记录,再遍历出最大值,因为是对称的所以从1切到n/2即可。
方法三:贪心算法:
(其实也是通过找规律得出来的)
贪心算法,大神们的数学推导,以3划分乘积最大。
3,代码:
方法一:这个是通过数学找的规律
class Solution {
public int cuttingRope(int n) {
/*
第一步:定义dp[n]的值的含义为:数字n的乘积最大值
n=2: 1+1 -->1*1=1; dp[2]=1;
n=3: 2+1 -->2*1=2; dp[3]=2;
n=4: 2+2 -->2*2=4; dp[4]=4;
n=5: 3+2 -->3*2=6; dp[5]=6;
貌似看不出规律,别急再多写几个
n=6: 3+3 -->3*3=4; dp[6]=9;
n=7: 4+3 -->4*3=12;-->dp[4]*3=12 dp[7]=12;
n=8: 5+3 -->6*3=12;-->dp[5]*3=18 dp[8]=18;
n=9: 6+3 -->9*3=12;-->dp[6]*3=27 dp[9]=27;
n=10: 7+3 -->12*3=36;-->dp[7]*3=12 dp[10]=36;
第二步:找到递推的规律:
通过上述分析,规律明显在n=7以后为
if(n>=7)
dp[n] = dp[n-3]*3;
第三步:找初始值:
初始值在第二步找规律已经找到了
n=2: 1+1 -->1*1=1; dp[2]=1;
n=3: 2+1 -->2*1=2; dp[3]=2;
n=4: 2+2 -->2*2=4; dp[4]=4;
n=5: 3+2 -->3*2=6; dp[5]=6;
n=6: 3+3 -->3*3=4; dp[6]=9;
*/
//1.创建数组-设置对应的含义,dp[n]为长度为 n 时候,最大的乘积 我们只需求出dp[n]
int[] dp = new int[n+7];
//3.确定初始值
dp[0]=0;
dp[1]=0;
dp[2]=1;
dp[3]=2;
dp[4]=4;
dp[5]=6;
dp[6]=9;
if(n<=6){return dp[n];}
//2.找到递推关系
for (int i = 7; i <= n; i++) {
dp[i] = dp[i-3]*3;
}
return dp[n];
}
}
方法二:动态规划:
class Solution {
//动态规划,每次都划分为f(i) * f(n-i),之前的值在dp数组已经记录,再遍历出最大值,因为是对称的所以从1切到n/2即可
public int cuttingRope(int n) {
if(n < 2) return 0;
if(n == 2) return 1;
if(n == 3) return 2;
int[] dp =new int[n+1];
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;//必须要到n = 4切3段时,因为不然公式不能套用
int max = 0;
for(int i = 4;i<=n;i++){
max = 0;
for(int j = 1;j<=i/2;j++){
int temp = dp[j] * dp[i-j];
if(temp > max){
max = temp;
}
dp[i] = max;
}
}
return dp[n];
}
}
方法三:贪心算法:
(其实也是通过找规律得出来的)
//贪心算法,大神们的数学推导,以3划分乘积最大
public int cuttingRope(int n) {
if(n < 2) return 0;
if(n == 2) return 1;
if(n == 3) return 2;
int a = n/3,b = n%3;
if(b == 0) {
return (int)Math.pow(3,a);
}else if(b == 1) {
return (int)Math.pow(3,a-1)*4;
}else {
return (int)Math.pow(3,a)*2;
}
}