【劍指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

 

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