【剑指offer】刷题:剪绳子问题

题目描述

给你一根长度为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。

输入描述:

输入一个数n,意义见题面。(2 <= n <= 60)

输出描述:

输出答案。

示例1

输入

8

输出

18

解题方法1:贪心算法

  • 当 number < 4时,最大乘积为 number-1,具体如下:

               number = 1:    最大乘积为 0

               number = 2:    最大乘积为1*1 = 1

               number = 3:    最大乘积为2*1 = 2

  • 当number = 4 时,最大乘积为number具体如下:  

               number = 4:    最大乘积为2*2 = 4

  • 当number>4时,即 number >= 5时,2 (n-2) > n, 3 (n-3) > n,即:将绳子剪成 2 和 (n-2) 或者 3(n-3)时,乘积大于不剪的乘积,因此需要把绳子剪成 2 或者 3。并且 3(n-3) >= 2(n-2),也就是说,当 n >= 5时,应该剪尽量多的3,可以使最后的乘积最大。

        对于长度为 number 的绳子,如果减掉 m 段后,最后剩下的一段绳子长度为 4 ,那我们不再裁剪出3,因为裁剪出两个2得到的乘积是4,比1*3大。

以贪心策略编写代码如下:

# -*- coding:utf-8 -*-
class Solution:
    def cutRope(self, number):
        if number < 4:
            return number - 1
        if number == 4:
            return 4

        ret = 1
        while number > 4:
            ret *= 3
            number = number - 3

        ret = ret * number
        return ret

解题方法2:贪心算法

长度为 n 的绳子,剪出的子绳子长度之积最大值为Max[n]

假设先剪出的一段长度为 i 的子绳子,那么  Max[n] 就等于 i * Max[n-i],所以问题就可以用动态规划的思路解决。

当 n = 2 时,Max[n]  = 1;

当 n = 3 时,Max[n] = 2;

当 n > 3 时,Max[n] = i * Max[n-i]; 其中 i 的范围是 [1, n-1]

以动态规划算法编写代码如下:

# -*- coding:utf-8 -*-
class Solution:
    def cutRope(self,number):
        MaxMulti = [0, 1, 1, 2] + [0] * (number -3)
        
        if number < 4:
            return MaxMulti[number]

        for i in range(2, number + 1):
            curMax = i
            for j in range(1, i):
                curMax = max(j * MaxMulti[i-j], curMax)
            MaxMulti[i] = curMax
        return MaxMulti[number]

 

参考:

https://blog.csdn.net/weixin_43955099/article/details/106094258

https://blog.csdn.net/weixin_46132790/article/details/106402609

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章