劍指Offer 14 剪繩子(Python)

2021-09-25 07:20:51 字數 2590 閱讀 7246

題目描述

給你一根長度為你的繩子,請把繩子剪成m段(m、n都是整數),n > 1 且 m > 1),每段繩子的長度記為k[0], k[1],…,k[m]。請問k[0] x k[1] x … x k[m]可能的最大乘積是多少?

示例:

當繩子長度是8時,我們把它剪成長度為2、3、3的三段,此時得到的最大乘積是18。
動態規劃

尋找規律f(n

)=ma

x(f(

i)∗f

(n−i

))

f(n)=max(f(i)*f(n-i))

f(n)=m

ax(f

(i)∗

f(n−

i)):

長度n = 0時,最大乘積也為0;

長度n = 1時,因為必需剪一刀,所以最大乘積也為0;

長度n = 2時,最大乘積為1x1=1;

長度n = 3時,最大乘積為1x2=2;

以上幾種情況比較特殊,需要單獨討論。

長度n = 4時,有兩種可能1x3=3和2x2=4,最大乘積為4;

長度n = 5時,有三種可能1x4=4、2x3等於6,最大乘積為6。

到這裡,我們似乎可以總結出乙個規律來解決問題:

從長度4開始,我們都可以將繩子看作剪成兩段,也就是將當前問題變成兩個子問題;

然後這兩個子問題,我們在前面必然已經討論過了。

例如,長度等於5時,可以看作1和4的子問題,1的最優解是1(這裡不需要剪),4的最優解是4,因此1x4=4;

同理也可以看作2和3的子問題,2的最優解是2(同樣不需要剪),3的最優解是3(也不需要剪),所以2x3=6;

我們只需要找出所有組合中最大的乙個即可。

ps:1、2、3作為子問題時不需要剪,這也是我們為什麼特殊討論的原因。

演算法時間複雜度o(n

2)

o(n^2)

o(n2

),空間複雜度o(n

)o(n)

o(n)

def

cutting

(length)

:if length <2:

return

0if length ==2:

return

1if length ==3:

return

2

products =[0

,1,2

,3]for i in

range(4

, length +1)

: max_product =

0# i必然由i-1, i-2 ,i-3

for j in

range

(i-3

, i)

: product = products[j]

* products[i-j]

if product > max_product:

max_product = product

return products[length]

if __name__ ==

"__main__"

:print

(cutting(8)

)

貪婪演算法

上題的時間和空間複雜度還是過大了,能不能再有一種方法簡化呢?

其實我們可以按以下策略剪繩子:當 n >= 5時,盡可能多地剪長度為3的繩子。

當 n >= 5時,我們可證 3(n-3)>=n 且 3(n-3) >= 2(n-2),因此應該竟可能多剪長度為3的繩子。

ps:我們的討論範圍始終在1,2,3,因為某種意義上,這3個數是這個問題的「基數」;

4可以看作的2和2或1和3的組合,比4大的數同理,因此不要問為什麼不盡量剪成長度為4。

時間和空間複雜度都為o(1

)o(1)

o(1)

def

cutting

(length)

:if length <2:

return

0if length ==2:

return

1if length ==3:

return

2# 剪成3的段數

times_of_3 = length //

3# 2x2比1x3更好

if length %3==

1:times_of_3 -=

1#剪成2的段數

times_of_2 =

(length -

3*times_of_3)//2

return(3

**times_of_3)*(

2**times_of_2)

if __name__ ==

"__main__"

:print

(cutting(5)

)

2019.8.20 動態規劃的範圍從(1,i)為(i-3,i)

劍指offer 14 剪繩子

分析 本題可以用動態規劃,也可以用貪心法。動態規劃 設f n 表示當繩子長n時可以得到的最大乘積,那麼假設在i處切一刀,就會得到數學式子f n max f i f n i 02等於4,但是當n大於等於5時,我們就要拆成盡可能多的3和剩下的2。如果要證明,我們可以證明當n大於5時,有3 n 3 2 n...

劍指offer 14 剪繩子

這種文章網上很多,沒什麼營養,我只是自己記錄一下。雖然現在不找工作了,但以後演算法能力肯定需要加強,想著能不能每天堅持一道題,其實真做起來還有點難 劍指offer以前都是邊看答案邊記下來,現在能不能靠自己寫出來呢。時間複雜度為o n2 空間複雜度為o n 有一點要注意,m不是乙個給定的引數。思路是,...

劍指Offer 14 剪繩子

nowcode 把一根繩子剪成多段,並且使得每段的長度乘積最大。n 2 return 1 2 1 1 n 10 return 36 10 3 3 4 盡可能多剪長度為 3 的繩子,並且不允許有長度為 1 的繩子出現。如果出現了,就從已經切好長度為 3 的繩子中拿出一段與長度為 1 的繩子重新組合,把...