算法 - 剑指Offer I. 剪绳子

题目

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

解题思路

这题很难, 我这边使用的是动态规划,可得出的结论是F(n)=MAX(F(i)*F(n-i)), 然后我们按照代码中的注释可以退出一下的值, 然后我们按照这部分规律可得从4开始, 值就可以使用动态规划了, 但是需要将F(1) = 1,F(2)=2,F(3) =3需要给前面的值重新赋值, 所以在遇到n<=3的时候, 我们直接返回一波答案即可, 后续需要重新赋值给前面的值,然后这里说下为啥使用j/2因为 可以减少迭代的次数, 如果也放给i, 这里dp[j] * dp[i -j]其实就等于后面的dp[i- j] * dp[j], 并不需要其实,还有注意的一点是, 每次得出dp中x的最大值后, 需要赋值过去, 不然无法继续迭代计算!然后具体的实现思路可以看代码中的注释解释, 并且代码实现如下。

Java代码实现

public class CuttingRope {
    //2 1 => 2
    //3 2 => 3
    //4 4 => F(4) = F(2)* F(2)
    //5 6 => F(5) = F(2)* F(3)
    //6 9 => F(6) = F(2)* F(4) = 2 * 4 = 8 < F(3)* F(3) = 3*3 = 9
    //7 12 => F(7) = F(2)* F(5) = 2 * 6 = 12 = F(3)* F(4) = 3 * 4 = 12
    //8 18 => F(8) = F(2)* F(6) = 2 * 9 = 18 = F(3)* F(5) = 3 * 6 = 18 > F(4) * F(4) = 16
    //9 27 => ...
    //10 36 => ...
    //11 48 => ...
    public int cuttingRope(int n) {
        if(n <= 3){
            return n - 1;
        }
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        int tmp = 0;
        for (int i = 4; i <= n; i++) {
            for (int j = 1; j <= i/2 ; j++) {
                tmp = Math.max(tmp, dp[j] * dp[i -j]);
            }
            dp[i] = tmp;
            tmp = 0;
        }
        return dp[n];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值