剑指Offer(58)-[Array&String]剪绳子

探讨了如何将长度为n的绳子剪成m段,以获得k[0]xk[1]x…xk[m]的最大乘积。通过动态规划方法,实现了Java解法,针对不同长度的绳子提供了最优切割策略。

点击查看剑指Offer全解【Java & Golang】实现

题目描述

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


思路

当绳子为2m和3m这两种情况时:
2m长的绳子:剪成2段,乘积为1
3m长的绳子:剪成2段(-- | -),乘积为2

当绳子大与等于4m时:
1m长的绳子

2m长的绳子不再拆分

3m长的绳子不再拆分

4m长的绳子可以尝试拆分为1m * 3m长的绳子最大乘积
或2m长的绳子最大乘积 * 2m长的绳子最大乘积,其中第二种选择的结果最大为4

5m长的绳子可以尝试拆分为1m * 4m长的绳子最大乘积或2m长的绳子最大乘积 * 3m长的绳子最大乘积,选择后者结果最大为6

这其实就是一个动态规划的过程,当绳子大于等于4m时:
dp[1] = 1
dp[2] = 2
dp[3] = 3
dp[4] = dp[2] * dp[2]
dp[5] = dp[2] * dp[3]

每个dp[i]表示的是长度为i的绳子最大的乘积(或自身的长度已经无需再拆小)

Java实现

import java.lang.Math;
public class Solution {
    public int cutRope(int target) {
        // 动态规划解法,dp表示绳子的长度:
        // 当长度为1时,最大乘积只能为1
        // 当长度为2时,最大乘积为1
        // 当长度为3时,最大乘积为2
        // 当长度大于等于4时,可以换分为不同的小段,每一段即一个dp
        switch (target) {
                case 2 : return 1;
                case 3 : return 2;
        }
        // 以下是可以分段的情形,dp1 ,2, 3直接就可使用
        int[] dp = new int[target + 1];
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        // 构造dp
        for (int i = 4; i <= target; i++) {
            int res = 0;
            for (int j = 1; j <= i/2; j++) {
                res = Math.max(dp[j] * dp[i - j], res);
            }
            dp[i] = res;
        }
        return dp[target];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值